Skip to main content
Francesko
Staff
Staff
February 12, 2026

Troubleshooting Tip: A Real-World TCP Failure scenario caused by delayed FIN-ACK in a stateful firewall

  • February 12, 2026
  • 0 replies
  • 578 views
Description

This article describes a realistic failure scenario involving a print or a print server that sends a delayed FIN-ACK with reused sequence numbers, causing a firewall to prematurely close the connection and break the print job.

Scope FortiGate.
Solution

Modern enterprise networks rely on stateful firewalls to track every TCP session. These devices expect strict compliance with TCP sequence numbers and teardown rules. When an endpoint violates these rules, even slightly, the firewall may terminate the session, even though both endpoints believe it is still alive.

 

The topology below shows how a normal session is established:

 

Drawing 18.png


A user sends a print job from a workstation to a network print server.

Device

IP

Client workstation

10.10.10.50

Print server

172.16.20.25

Stateful firewall

Between both networks


The print job is sent using TCP port 9100.

 

Normal session setup:

The TCP session is established normally.

  • Client → Server   SYN
  • Server → Client   SYN-ACK
  • Client → Server   ACK

The firewall records the session and tracks the sequence numbers:

  • Client SEQ starts at 1000
  • Server SEQ starts at 5000

The print job is transmitted successfully.

 

The print-server initiates Session-Close:

When the job completes, the print server closes the connection first. It sends:

  • FIN, ACK
  • Seq = 8000
  • Ack = 3000

The firewall now expects the next server packet to have:

  • Seq = 8001

The client responds correctly:

  • ACK
  • Ack = 8001

At this point, the connection is halfway closed.

 

For any of the reasons outlined below, duplicate FIN-ACKs with the same sequence number may reach the firewall from different print jobs:

  • Network congestion.
  • High printer load: multiple printers behind a print server with numerous concurrent print jobs.
  • Possible TCP stack implementation issue on the printer, resulting in delays or sequence number reuse.

Example of duplicate-packet behavior, showing the same sequence number in both FIN-ACK packets:

  • FIN, ACK
  • Seq = 8001
  • Ack = 3000

 

Upon receiving the first FIN-ACK, the firewall and client terminate their connections. However, while the duplicate FIN-ACK with the same sequence number is delayed, the firewall has already closed the session, but a printer on the print-server network may still await the client's final acknowledgment.

 

In this scenario, the FortiGate debug flow will display a 'no session matched' message for the second FIN-ACK:

 

2026-02-02 06:59:24 id=65308 trace_id=55 func=print_pkt_detail line=5811 msg="vd-root received a packet(proto=6, 10.10.10.50:55141->172.16.20.5:9100) tun_id=0.0.0.0 from port9. flag [F.], seq 8001, ack 3000, win 8212"

2026-02-02 06:59:24 id=65308 trace_id=55 func=fw_forward_dirty_handler line=394 msg="no session matched"

 

The packet will be dropped and the impact on the print job could be:

  • The printer may appear to hang.
  • The job could be marked as failed.
  • The printer may be shown as offline.

 

Conclusion:

A single reused sequence number, combined with a delayed or duplicate FIN-ACK from a different flow using the same sequence number, can cause a stateful firewall to mark a valid TCP session as invalid. During print jobs, this leads to intermittent failures, typically occurring under high load or when multiple printers of the same model are connected behind a print server.

 

Workaround and solution:

  1. Configure bidirectional firewall policies: Ensure each firewall has at least two policies for traffic in both directions:
    • Client to Print-Server
    • Print-Server to Client

  2. Allow TCP session creation without SYN: Enable the following setting to permit the firewall to establish TCP sessions without requiring a SYN packet:

    config system settings
        set tcp-session-without-syn enable
    end

  3. Update printer related firewall policies:

    config firewall policy
        edit <policyid>
            set tcp-session-without-syn all
    end

 

This ensures that any remaining FIN-ACK packets can be processed even after the session is closed, with the firewall creating a new session if necessary.


Note: For security purposes, bidirectional firewall policies should restrict traffic to the correct subnets and limit services to only the required ports, rather than allowing all ports.

 

Sample debug flow showing behavior with tcp-session-without-syn configured for all sessions:

 

2026-02-02 06:59:24 id=65308 trace_id=111 func=init_ip_session_common line=6204 msg="allocate a new session-0001384a"
2026-02-02 06:59:24 id=65308 trace_id=111 func=iprope_dnat_check line=5481 msg="in-[port9], out-[]"
2026-02-02 06:59:24 id=65308 trace_id=111 func=iprope_dnat_tree_check line=824 msg="len=0"
2026-02-02 06:59:24 id=65308 trace_id=111 func=iprope_dnat_check line=5506 msg="result: skb_flags-02000002, vid-0, ret-no-match, act-accept, flag-00000000"
2026-02-02 06:59:24 id=65308 trace_id=111 func=__vf_ip_route_input_rcu line=1989 msg="find a route: flag=80000000 gw-0.0.0.0 via root"
2026-02-02 06:59:24 id=65308 trace_id=111 func=iprope_access_proxy_check line=458 msg="in-[port9], out-[], skb_flags-02000002, vid-0"
2026-02-02 06:59:24 id=65308 trace_id=111 func=__iprope_check line=2404 msg="gnum-100017, check-ffffffffa002c1a0"
2026-02-02 06:59:24 id=65308 trace_id=111 func=iprope_policy_group_check line=4903 msg="after check: ret-no-match, act-accept, flag-00000000, flag2-00000000"
2026-02-02 06:59:24 id=65308 trace_id=111 func=__iprope_fwd_check line=810 msg="in-[port9], out-[port2], skb_flags-02000002, vid-0, app_id: 0, url_cat_id: 0"
2026-02-02 06:59:24 id=65308 trace_id=111 func=__iprope_tree_check line=535 msg="gnum-100004, use addr/intf hash, len=2"
2026-02-02 06:59:24 id=65308 trace_id=111 func=__iprope_check_one_policy line=2374 msg="policy-1 is matched, act-accept"

 

Related articles: