01Before you touch anything
Three habits save more outages than any command: keep a current config backup, make changes under change control, and document what you altered and when. Ninety percent of "the firewall broke" tickets resolve to "a change was made" — so the fastest diagnostic is often a diff against a known-good config.
execute backup config flash before-change # snapshot on-box before you start show | grep -f # full running config to compare off-box later
02The built-in toolbox (GUI + CLI)
You rarely need external tools. Reach for these first:
| Log Viewer (GUI) | Forward traffic, events, security, VPN, UTM — filter on Deny and on a source IP. |
|---|---|
| Policy Lookup (GUI) | Enter source/dest/port/proto → it tells you the exact policy that would match. |
| FortiView (GUI) | Top talkers, destinations, and threats — spot the anomaly visually. |
| Routing Monitor (GUI) | The active routing table (Network → monitor). |
| Packet Capture (GUI/CLI) | Grab traffic on an interface for offline analysis. |
The two CLI families are get (show current state) and diagnose (dig deeper). Your orientation set:
get system status # model, firmware, serial, HA state get system performance status # CPU, memory, sessions, setup rate, uptime get router info routing-table all # the routing table (CLI form of Routing Monitor) diagnose sys session stat # session table totals & setup rate
Version: FortiGate-100F v7.4.5,build... CPU states: 3% user 2% system 0% nice 95% idle Memory: 61% used Sessions: 18423 (setup rate 214/s)
03The two commands that solve most cases
When you don't know why traffic is failing, these answer it. Debug flow makes the FortiGate narrate its decision for a packet — route lookup, policy match, NAT, UTM verdict. Sniffer proves whether the packet arrived and whether a reply came back.
Debug flow — "what did you decide, and why?"
diagnose debug reset diagnose debug flow filter saddr 10.10.10.20 # the client diagnose debug flow filter daddr 203.0.113.50 # the destination diagnose debug flow filter dport 443 diagnose debug flow show function-name enable diagnose debug flow show iprope enable # show the policy-lookup decision diagnose debug console timestamp enable diagnose debug flow trace start 10 # follow the next 10 matching packets diagnose debug enable # … generate the traffic now … diagnose debug disable diagnose debug flow trace stop diagnose debug reset # always reset when done
msg="vd-root received a packet(proto=6, 10.10.10.20:51244->203.0.113.50:443)" msg="allocate a new session" msg="find a route: gw-203.0.113.1 via wan1" msg="Denied by forward policy check (policy 0)" <- no matching policy = implicit deny
That last line is the whole diagnosis: policy 0 is the implicit deny — the packet reached
the box and was routed, but no policy accepted it. Now you know it's a policy problem, not a
routing or L2 one.
Sniffer — "did the packet even arrive, and did anyone answer?"
diagnose sniffer packet any 'host 10.10.10.20 and port 443' 4 0 a # any = all interfaces · verbosity 4 = headers + iface names · count 0 = until Ctrl-C · a = absolute time
2026-07-31 09:14:02.114 port2 in 10.10.10.20.51244 -> 203.0.113.50.443: syn 2026-07-31 09:14:02.114 wan1 out 10.10.10.20.51244 -> 203.0.113.50.443: syn # …no syn-ack coming back on wan1 → the problem is upstream/return-path, not inside the client LAN
diagnosis = sniffer (did it arrive / reply?) + debug flow (what did the FortiGate decide?)
04Connectivity problems
Work bottom-up, and let each command rule out a layer:
- Interface & link. Is the port up with the right IP?
- Route. Does a default (or specific) route point out the correct egress?
- Policy & NAT. Does a policy accept the flow, and is NAT on for internet-bound traffic?
- Name resolution. Can the box (and the client) resolve DNS at all?
get system interface physical # link state + speed/duplex per port diagnose hardware deviceinfo nic wan1 # errors, drops, carrier on the physical NIC get router info routing-table all # is there a route out, via the right interface? execute ping-options source 10.10.10.1 # test from the LAN-facing IP… execute ping 203.0.113.50 # …to prove egress + return path
wan1: link up, speed 1000Mbps, duplex full S* 0.0.0.0/0 [10/0] via 203.0.113.1, wan1 --- 203.0.113.50 ping statistics --- 5 packets transmitted, 5 received, 0% loss
Caviar: if the ping from the FortiGate works but the client's doesn't, the box is fine — the issue is a policy/NAT or a return route for the client subnet. Confirm with Policy Lookup, then a debug flow filtered on the client IP (§03).
05Policy misconfigurations
Policies are evaluated top to bottom, first match wins. The usual failures: a broader policy above shadows yours, the interface pair is wrong, or a UTM profile (not the policy) is doing the blocking. Start with Policy Lookup, then trace:
diagnose debug flow filter saddr 10.10.10.20 daddr 203.0.113.50 dport 443 diagnose debug flow show iprope enable diagnose debug flow trace start 5 diagnose debug enable # …generate traffic, then disable/reset as in §03…
msg="Match policy id 7" <- which policy actually caught it msg="utm: proxy-based inspection ... blocked (webfilter)" <- policy allowed, UTM denied
Caviar: "allowed by policy but still blocked" almost always means a security profile — web filter, IPS, application control, or SSL inspection. The debug flow names the culprit; then fix the profile, not the policy. Cross-check the policy ID column in the forward-traffic log to confirm which rule matched in production.
06VPN tunnels (IPsec & SSL-VPN)
IPsec site-to-site. Diagnose it in phases — Phase 1 (IKE) first, then Phase 2 (IPsec), then policy/route.
get vpn ipsec tunnel summary # up/down + rx/tx per tunnel at a glance diagnose vpn ike gateway list # Phase 1 (IKE) state per peer diagnose vpn tunnel list # Phase 2 SAs, selectors, encryption # live IKE negotiation: diagnose debug application ike -1 diagnose debug enable # watch it try to come up, then: diagnose debug reset
gateway 'HQ-to-Branch' ike v2 status: established <- P1 up # common P1/P2 failures: proposal mismatch, PSK mismatch, wrong peer/gateway IP, # or Phase 2 selector (subnet) mismatch between the two ends
If both phases are up but traffic still fails, it's the boring stuff: a firewall policy permitting tunnel traffic in both directions, and a route pointing the remote subnet at the IPsec interface.
SSL-VPN. Check reachability, auth, and the internal path in that order:
get vpn ssl monitor # who is connected, and their assigned IPs diagnose debug application sslvpn -1 diagnose debug enable # watch a login attempt; then reset
SSL-VPN Login Users: user 'jdoe' tunnel-ip 10.212.134.200 ok # if login fails: credentials/auth server, or the user isn't in the mapped group # if login ok but no internal access: missing policy (ssl.root → internal) or no return route to the IP pool
07Performance & conserve mode
High CPU, high memory, or "conserve mode" throttling usually traces to one process, one session storm, or memory pressure.
get system performance status # CPU/memory/session snapshot & setup rate diagnose sys top 2 20 # top processes by CPU (refresh 2s, 20 lines) — 'q' to quit diagnose sys session stat # session count & setup rate (SYN floods show here) diagnose hardware sysinfo conserve # are we in conserve mode, and the memory thresholds
memory conserve mode: on total 2048MB used 1740MB (85%) green:82% red:88% # entered conserve at the red threshold → find the memory hog (diagnose sys top) or reduce # proxy-based inspection / session load; sustained high setup rate hints at a flood or a loop.
Caviar: a single client generating tens of thousands of sessions is a classic culprit —
filter the session table by source (diagnose sys session filter src <ip> then
diagnose sys session list) to catch a loop or malware before blaming the box.
08DNS & routing quick checks
execute ping FortiGuard.net # does the box resolve + reach the internet by name? diagnose test application dnsproxy 6 # the FortiGate's own DNS cache/servers get router info routing-table details 203.0.113.50 # exactly which route a destination will use diagnose ip router ... / diagnose firewall proute list # policy routes (they win over the routing table)
Caviar: a destination that "should work" but doesn't often has a policy
route (PBR) silently steering it out the wrong interface — policy routes are evaluated
before the routing table, so always check proute when a route looks correct but
traffic goes the wrong way. (See also the
FQDN object / DNS round-robin trap.)
09A repeatable method
When you're stuck, run the same loop every time — it turns "the firewall is broken" into a decision tree:
- Reproduce & scope. One client, one destination, one port. Vague reports waste hours.
- Did it arrive? Sniffer on the ingress interface. No packet → it's upstream/L2/routing to the box.
- What was decided? Debug flow. It names the route, the policy, the NAT, the UTM verdict.
- Fix the named thing. Policy, profile, route, or NAT — whatever the trace pointed at.
- Confirm & document. Re-test the exact flow, then note the change (§01).
method = reproduce + sniff (arrived?) + debug flow (verdict?) + fix the named layer + verify
10References
- Fortinet Docs — FortiGate Administration Guide (debug flow, sniffer, diagnostics).
- Related field notes: FortiGate FQDN object connectivity fails · FortiBleed response & hardening.
- Drive the box by API instead of the GUI: Insomnia as an API remote control.
- All Troubleshooting notes.