Initial troubleshooting for traffic blocked by FortiGate
Confirmed 9/20/2026
Problem
Traffic expected to traverse a FortiGate is blocked or does not reach its destination. This article provides an initial diagnostic workflow and identifies the evidence to collect before opening a TAC case.
Symptoms
A new or previously working connection fails across FortiGate. Debug flow may report `Denied by forward policy check`, `iprope_in_check() check failed, drop`, or `reverse path check fail, drop`. Allowed traffic may instead show `sent to AV`, `sent to IPS`, `Trying to offloading session from port1 to wan1`, or `Find an existing session, id-0xxxxxxxx, reply direction`.
Environment
FortiGate, including standalone and HA deployments. The workflow applies to firewall policies, UTM/security profiles, flow-based or proxy-based inspection, NAT, routing, hardware-accelerated models, authentication and user-group policies, and SIP/VoIP traffic.
Root Cause
Possible causes include an incomplete new deployment, a firmware or configuration change, unsynchronized HA members, inconsistent HA firmware, missing connectivity or routes, an incorrect firewall-policy match, restrictive security profiles, inspection-mode behavior, authentication or user-group handling, custom-service settings, or a Layer 7 issue. The specific cause must be established from logs, debug flow, packet captures, routing, and session data.
Solution
-
Establish whether the traffic ever worked.
- For a new implementation that has never worked, verify that every step in the applicable setup guide was completed. When opening a TAC case, provide the guide link and a configuration backup.
- If the traffic previously worked, identify all changes made since the last known-good state, including firmware, policy, and inspection-profile changes.
-
Check the platform after an upgrade.
- For a standalone upgrade, review the release notes for known issues and test internet and DNS reachability:
exec ping pu.bl.ic.IP
exec ping service.fortiguard.net
- For an HA upgrade, confirm that both members are synchronized and run the same firmware:
get system status
- Confirm that the primary unit can reach both WAN and LAN destinations:
exec ping pu.bl.ic.IP
exec ping lo.ca.l.IP
- If either test fails, inspect the routing table:
get router info routing-table all
get router info routing-table detail x.x.x.x
- If downgrade is required, collect all logs or contact support before reverting; otherwise, determining the cause may not be possible. The previous firmware is retained in memory and can be used for a quick downgrade.
-
Review and, where possible, revert the last policy or inspection-profile change.
- If reverting restores traffic, the changed policy or profile has isolated the cause. Adjust the recently added, removed, or modified settings so that the required traffic is allowed.
- If reverting does not restore traffic, continue with the following diagnostics and retain the output for TAC.
-
Confirm the expected firewall policy.
- Identify the policy that should allow the connection and record its policy ID.
- Perform a CLI policy lookup and verify
policy_id=in the output:
diagnose firewall iprope lookup <source ip> <source port number> <destination ip> <destination port number> <protocol> <incoming interface>
- If a session exists, review all UTM profiles applied to the matched policy, including Antivirus, WebFilter, and IPS. Remove profiles one at a time until traffic is restored.
- Test whether traffic passes after changing the policy inspection mode from proxy-based to flow-based.
-
Review available logs.
- Ensure policy logging is enabled, then inspect traffic logs and security logs such as Antivirus, WebFilter, and IPS.
- Determine whether the block was caused by a firewall policy or a security profile. Logs can identify the policy type, policy ID, and sometimes the reason for the block.
- Export a small, relevant set of records from the logging platform, such as the FortiGate GUI, FortiAnalyzer, FortiCloud, or Syslog, and attach it to the TAC case.
-
Collect a packet capture.
- On hardware-accelerated models, temporarily disable hardware acceleration so the traffic can be captured.
- Prefer a CLI capture while recording the SSH output.
- For SIP/VoIP issues, a packet capture—normally filtered with
port 5060—is required together with a configuration backup from the GUIGlobalcontext. - Example capture for ICMP between
172.16.1.2and8.8.8.8:
diagnose sniffer packet any "host 172.16.1.2 and host 8.8.8.8 and icmp" 4 3 l
The source describes 4 as capturing packet headers, 3 as the packet count, and lowercase l as providing timestamps in local firewall time. It also contains the inconsistent wording Values 4 2 l and says “only 3 packets (2)”; use the exact command above when reproducing the example.
Expected working output:
Using Original Sniffing Mode
interfaces=[any]
filters=[host 172.16.1.2 and host 8.8.8.8 and icmp]
Using Original Sniffing Mode
interfaces=[any]
filters=[icmp]
2024-08-16 22:04:21.844412 port2 in 172.16.1.2 -> 8.8.8.8: icmp: echo request
2024-08-16 22:04:21.845467 port1 out 10.191.19.117 -> 8.8.8.8: icmp: echo request
2024-08-16 22:04:21.847570 port1 in 8.8.8.8 -> 10.191.19.117: icmp: echo reply
2024-08-16 22:04:21.847776 port2 out 8.8.8.8 -> 172.16.1.2: icmp: echo reply
This confirms arrival on port2, SNAT and transmission through port1, return traffic on port1, and forwarding back to the client through port2.
- Run debug flow for the affected connection.
- The following example restricts output to traffic between
172.16.1.2and8.8.8.8, uses ICMP protocol number1, displays iprope and function names, enables timestamps, and captures two packets:
- The following example restricts output to traffic between
diagnose debug flow filter add 172.16.1.2 8.8.8.8 and
diagnose debug flow filter proto 1
diagnose debug flow show iprope enable
diagnose debug flow show function-name enable
diagnose debug console time enable
diagnose debug enable
diagnose debug flow trace start 2
- Set the trace count to a reasonable value when more data is necessary.
- Stop and reset debugging afterward:
diagnose debug disable
diagnose debug reset
- Interpret common blocking messages as follows:
Denied by forward policy check: no permitting forward policy was applied.iprope_in_check() check failed, drop: the iprope check failed.reverse path check fail, drop: reverse-path validation failed.
- Common indications of allowed or established traffic include:
sent to AVorsent to IPS: traffic was submitted to Antivirus or flow-based inspection.Trying to offloading session from port1 to wan1: the session is being copied from one interface to another.Find an existing session, id-0xxxxxxxx, reply direction: a session already exists and traffic is flowing; investigate a possible Layer 7 issue with packet capture.
- Analyze the working debug-flow example.
FGT1 # 2024-08-16 21:44:36 id=65308 trace_id=1 func=print_pkt_detail line=5894 msg="vd-root:0 received a packet(proto=1, 172.16.1.2:1->8.8.8.8:2048) tun_id=0.0.0.0 from port2. type=8, code=0, id=1, seq=3."
2024-08-16 21:44:36 id=65308 trace_id=1 func=init_ip_session_common line=6080 msg="allocate a new session-000a6c90, tun_id=0.0.0.0"
2024-08-16 21:44:36 id=65308 trace_id=1 func=iprope_dnat_check line=5281 msg="in-[port2], out-[]"
2024-08-16 21:44:36 id=65308 trace_id=1 func=iprope_dnat_tree_check line=824 msg="len=0"
2024-08-16 21:44:36 id=65308 trace_id=1 func=iprope_dnat_check line=5293 msg="result: skb_flags-02000000, vid-0, ret-no-match, act-accept, flag-00000000"
2024-08-16 21:44:36 id=65308 trace_id=1 func=__vf_ip_route_input_rcu line=1990 msg="find a route: flag=00000000 gw-10.191.31.254 via port1"
2024-08-16 21:44:37 id=65308 trace_id=1 func=iprope_fwd_check line=768 msg="in-[port2], out-[port1], skb_flags-02000000, vid-0, app_id: 0, url_cat_id: 0"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_tree_check line=535 msg="gnum-100004, use addr/intf hash, len=2"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policyline=2033 msg="checked gnum-100004 policy-2, ret-matched, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_user_identity_check line=1807 msg="ret-matched"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check line=2281 msg="gnum-4e21, check-00000000a905ccbb"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-4294967295, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-9, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-10, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-11, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-12, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-1, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-14, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-5, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-16, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-2, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-3, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-4, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-8, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-6, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-6, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-6, ret-no-match, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e21 policy-7, ret-matched, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2251 msg="policy-7 is matched, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check line=2298 msg="gnum-4e21 check result: ret-matched, act-accept, flag-00202000, flag2-00000000"
2024-08-16 21:44:37 id=65308 trace_id=1 func=get_new_addr line=1213 msg="find SNAT: IP-10.191.19.117(from IPPOOL), port-60418"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__iprope_check_one_policy line=2251 msg="policy-2 is matched, act-accept"
2024-08-16 21:44:37 id=65308 trace_id=1 func=iprope_fwd_check line=805 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-2"
2024-08-16 21:44:37 id=65308 trace_id=1 func=iprope_fwd_auth_check line=824 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-2"
2024-08-16 21:44:37 id=65308 trace_id=1 func=iprope_reverse_dnat_check line=1292 msg="in-[port2], out-[port1], skb_flags-02000000, vid-0"
2024-08-16 21:44:37 id=65308 trace_id=1 func=iprope_reverse_dnat_tree_check line=916 msg="len=0"
2024-08-16 21:44:37 id=65308 trace_id=1 func=fw_forward_handler line=989 msg="Allowed by Policy-2: SNAT"
2024-08-16 21:44:37 id=65308 trace_id=1 func=ip_session_confirm_final line=3113 msg="npu_state=0x1100, hook=4"
2024-08-16 21:44:37 id=65308 trace_id=1 func=ids_receive line=431 msg="send to ips"
2024-08-16 21:44:37 id=65308 trace_id=1 func=__ip_session_run_tuple line=3458 msg="SNAT 172.16.1.2->10.191.19.117:60418"
2024-08-16 21:44:37 id=65308 trace_id=2 func=print_pkt_detail line=5894 msg="vd-root:0 received a packet(proto=1, 8.8.8.8:60418->10.191.19.117:0) tun_id=0.0.0.0 from port1. type=0, code=0, id=60418, seq=3."
2024-08-16 21:44:37 id=65308 trace_id=2 func=resolve_ip_tuple_fast line=5982 msg="Find an existing session, id-000a6c90, reply direction"
2024-08-16 21:44:37 id=65308 trace_id=2 func=__ip_session_run_tuple line=3471 msg="DNAT 10.191.19.117:0->172.16.1.2:1"
2024-08-16 21:44:37 id=65308 trace_id=2 func=__vf_ip_route_input_rcu line=1990 msg="find a route: flag=00000000 gw-0.0.0.0 via port2"
2024-08-16 21:44:37 id=65308 trace_id=2 func=npu_handle_session44 line=1327 msg="Trying to offloading session from port1 to port2, skb.npu_flag=00000000 ses.state=00002200 ses.npu_state=0x00001108"
2024-08-16 21:44:37 id=65308 trace_id=2 func=fw_forward_dirty_handler line=439 msg="state=00002200, state2=00000000, npu_state=00001108"
2024-08-16 21:44:37 id=65308 trace_id=2 func=ids_receive line=431 msg="send to ips"
Key observations are:
trace_id=1contains FortiGate actions for the first packet;trace_id=2identifies the second packet.- The initial packet enters
port2, receives a route through gateway10.191.31.254onport1, matches policy2, is accepted, and is SNATed from172.16.1.2to IP-pool address10.191.19.117using port60418. - The reply enters
port1, matches existing session000a6c90, is DNATed back to172.16.1.2, and is routed throughport2. - Although the first debug line contains
172.16.1.2, the source commentary refers to traffic from172.16.1.1; preserve the actual debug output when interpreting the trace.
- Validate routing for both endpoints.
- Check the route toward the client:
get router info routing-table details 172.16.1.2
Expected example:
Routing table for VRF=0
Routing entry for 172.16.1.0/24
Known via "connected", distance 0, metric 0, best
* is directly connected, port2
- Confirm the
port2interface addressing:
show system interface port2
Example configuration:
config system interface
edit "port2"
set vdom "root"
set ip 172.16.1.1 255.255.255.0
set type physical
set snmp-index 2
end
next
end
- Check the route toward the destination:
get router info routing-table details 8.8.8.8
Expected example:
Routing table for VRF=0
Routing entry for 0.0.0.0/0
Known via "static", distance 10, metric 0, best
* vrf 0 10.191.31.254, via port1
Example static-route configuration:
config router static
edit 1
set gateway 10.191.31.254
set dst 0.0.0.0 0.0.0.0
set device "port1"
next
end
The connected route should correspond to ingress port2, and the static default route should correspond to egress port1 seen in the sniffer.
- Inspect the session table.
- Filter on source, destination, and protocol, then list the matching session:
diagnose sys session filter src 172.16.1.2
diagnose sys session filter dst 8.8.8.8
diagnose sys session filter proto 1
diagnose sys session list
Working example:
session info: proto=1 proto_state=00 duration=2 expire=59 timeout=0 flags=00000000 socktype=0 sockport=0 av_idx=0 use=4
origin-shaper=
reply-shaper=
per_ip_shaper=
class_id=0 ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255
state=may_dirty ndr
statistic(bytes/packets/allow_err): org=180/3/1 reply=180/3/1 tuples=3
tx speed(Bps/kbps): 65/0 rx speed(Bps/kbps): 65/0
orgin->sink: org pre->post, reply pre->post dev=4->3/3->4 gwy=10.191.31.254/0.0.0.0
hook=post dir=org act=snat 172.16.1.2:1->8.8.8.8:8(10.191.19.117:60418)
hook=pre dir=reply act=dnat 8.8.8.8:60418->10.191.19.117:0(172.16.1.2:1)
hook=post dir=reply act=noop 8.8.8.8:1->172.16.1.2:0(0.0.0.0:0)
misc=0 policy_id=2 pol_uuid_idx=15749 auth_info=0 chk_client_info=0 vd=0
serial=000a7123 tos=ff/ff app_list=0 app=0 url_cat=0
rpdb_link_id=00000000 ngfwid=n/a
npu_state=0x001108
no_ofld_reason: redir-to-ips denied-by-nturbo
total session 1
- Focus on the path line:
orgin->sink: org pre->post, reply pre->post dev=4->3/3->4 gwy=10.191.31.254/0.0.0.0
- Map the interface indexes with:
diagnose ip address list
Example:
IP=10.191.19.117->10.191.19.117/255.255.240.0 index=3 devname=port1
IP=172.16.1.1->172.16.1.1/255.255.255.0 index=4 devname=port2
IP=192.168.1.254->192.168.1.254/255.255.255.0 index=8 devname=port6
IP=127.0.0.1->127.0.0.1/255.0.0.0 index=14 devname=root
IP=10.255.1.1->10.255.1.1/255.255.255.0 index=18 devname=fortilink
IP=127.0.0.1->127.0.0.1/255.0.0.0 index=19 devname=vsys_ha
IP=127.0.0.1->127.0.0.1/255.0.0.0 index=21 devname=vsys_fgfm
Here, `dev=4->3/3->4` maps original traffic from `port2` to `port1` and reply traffic from `port1` to `port2`.
11. Check special policy conditions. - If policies use authentication or user groups, collect and review the corresponding authentication diagnostics. - For custom services applied to specific subnets in inbound or outbound policies, modify only the required TCP/UDP port range. Changing other options, including source port or IP range, can prevent the traffic from matching the policy.
- Prepare the TAC case.
- Attach the configuration backup taken from the GUI
Globalcontext, relevant traffic or security logs, packet captures, debug-flow output, and a debug log snapshot of system parameters. - For complex topologies, document the entire path, for example:
PC -> port1 (vlan 100, vdom TEST, policy 17) -> zone PROD -> VDOM link TEST_to_PROD -> port9 (VLAN 15, policy 413) -> internet port wa1. - Include the setup-guide link for new deployments and note all observations and tests. Providing these items when the case is created avoids additional collection requests and can shorten resolution time.
- Attach the configuration backup taken from the GUI
Verification
Confirm all of the following: the expected policy ID is matched and shows act-accept; debug flow identifies the correct ingress and egress interfaces; routing entries point to those interfaces; packet capture shows the request entering and leaving FortiGate and the reply returning and reaching the client; session output contains both original and reply tuples with the expected SNAT/DNAT; and the interface indexes map to the expected ports. The supplied working example uses policy 2, ingress port2, egress port1, gateway 10.191.31.254, and SNAT address 10.191.19.117. If any value differs unexpectedly, inspect that stage of the path.
Rollback
If the failure followed a policy or profile change, revert the last change and retest. If traffic returns, fine-tune that policy or profile. If a firmware downgrade is necessary, first collect all logs or contact support; otherwise, later root-cause analysis may not be possible. The previous firmware version is retained in memory for a quick downgrade. Re-enable any hardware acceleration temporarily disabled for packet capture after evidence collection.
Tags
No tags yet.
Community rating
— / 5 (0)
Discussion (0)
No comments yet.