Symptoms
You're staring at the FortiGate dashboard and the VPN tunnel that was working fine yesterday is now showing a red indicator. Users are calling in saying they can't reach the remote site, applications are timing out, and nobody's happy. The symptom picture usually falls into one of these buckets: the tunnel shows Down in VPN > IPsec Tunnels, pings to remote subnets fail silently, or traffic routes out the wrong interface and hits the internet instead of the tunnel.
In the FortiGate event logs you might see entries like these:
ike 0: comes 203.0.113.45:500->198.51.100.10:500,ifindex=3....
ike 0:TUN-SOLVENET:1234: no suitable proposal found
ike 0:TUN-SOLVENET: negotiation failure
Or maybe the tunnel is stuck in a perpetual connecting state, never fully establishing. Sometimes it comes up momentarily and then drops again every few minutes — that's usually DPD-related and we'll cover that. Let's go through each common failure mode with real commands and actual output so you can pinpoint which one you're dealing with.
Root Cause 1: Phase 1 Proposal Mismatch
This is the most frequent culprit, especially when a tunnel is being established between two different vendors or when the remote admin quietly updated their config without letting you know. Phase 1 — the IKE Security Association — is where both peers agree on how they'll authenticate and what algorithms they'll use to protect the IKE channel itself. If there's no overlapping proposal, negotiation dies immediately with no ambiguity.
The mismatch can be in the encryption algorithm (AES-128 vs AES-256), the hash and integrity algorithm (SHA-1 vs SHA-256), the Diffie-Hellman group (Group 5 vs Group 14), or the IKE version itself (IKEv1 vs IKEv2). In my experience, DH group mismatches are the sneakiest because both sides might be using AES256 with SHA256 but one peer is on Group 5 and the other on Group 14 — and that single difference kills the entire negotiation.
How to Identify It
Enable IKE debug on the FortiGate and watch the output live:
diagnose debug reset
diagnose debug application ike -1
diagnose debug enable
Trigger the tunnel by sending traffic across it or manually initiating it from the GUI. Watch for this pattern in the output:
ike 0:TUN-SOLVENET:1234: peer proposal:
encr: AES-CBC(128) integ: HMAC-SHA1-96 prf: HMAC-SHA1 dh: MODP_1024
ike 0:TUN-SOLVENET:1234: local proposal:
encr: AES-CBC(256) integ: HMAC-SHA2-256-128 prf: HMAC-SHA2-256 dh: MODP_2048
ike 0:TUN-SOLVENET:1234: no matching proposal found
ike 0:TUN-SOLVENET: negotiation failure
That output is diagnostic gold — it tells you exactly what the remote peer is offering versus what your FortiGate expects. You can also check the current IKE gateway state to confirm Phase 1 never completed:
diagnose vpn ike gateway list name TUN-SOLVENET
If you see
IKE SA: created 0/1 established 0/1, Phase 1 hasn't made it through.
How to Fix It
Align the proposals with the remote peer. Either coordinate on a common set or add their proposal to your Phase 1 config:
config vpn ipsec phase1-interface
edit "TUN-SOLVENET"
set proposal aes256-sha256 aes128-sha256
set dhgrp 14 5
set ike-version 2
next
end
After saving, flush and re-establish the tunnel:
diagnose vpn ike gateway flush name TUN-SOLVENET
diagnose vpn tunnel flush TUN-SOLVENET
Always disable debug when done to avoid a performance hit on the firewall:
diagnose debug disable
diagnose debug reset
Root Cause 2: Phase 2 Mismatch
Phase 2 negotiates the actual IPSec Security Association — the parameters used to encrypt the data traffic flowing through the tunnel. Even if Phase 1 comes up perfectly, a Phase 2 mismatch stops data traffic dead. The usual mismatches are the encryption and integrity algorithm pair, the PFS group setting, and — most insidiously — the traffic selectors that define which source and destination subnets the tunnel protects.
Traffic selector mismatches are particularly frustrating because Phase 1 shows green in the GUI but no packets move. I've watched this exact scenario play out when a remote site expanded their internal addressing from a /24 to a /22 and updated their firewall, but nobody informed the team managing the FortiGate side. The IKE negotiation finishes Phase 1 fine, then silently fails at Phase 2 because the selectors don't agree.
How to Identify It
With IKE debug running, a traffic selector rejection looks like this:
ike 0:TUN-SOLVENET:TUN-SOLVENET:1234: initiating CHILD_SA
ike 0:TUN-SOLVENET:TUN-SOLVENET:1234: TSi 192.168.10.0/255.255.255.0
ike 0:TUN-SOLVENET:TUN-SOLVENET:1234: TSr 10.50.0.0/255.255.0.0
ike 0:TUN-SOLVENET:TUN-SOLVENET:1234: TS_UNACCEPTABLE
ike 0:TUN-SOLVENET:TUN-SOLVENET: CHILD_SA negotiation failed
TS_UNACCEPTABLEmeans the remote peer rejected the traffic selectors your FortiGate proposed. Review your Phase 2 config and compare with what the remote side expects:
show vpn ipsec phase2-interface
Then verify whether any IPSec SAs are actually established:
diagnose vpn tunnel list name TUN-SOLVENET
No child SAs listed and
proxyid_num=0confirms Phase 2 never completed.
How to Fix It
Correct the Phase 2 configuration to match the remote peer exactly — subnet masks, algorithm choices, and PFS settings all need to line up:
config vpn ipsec phase2-interface
edit "TUN-SOLVENET-P2"
set phase1name "TUN-SOLVENET"
set proposal aes256-sha256 aes128-sha256
set pfs enable
set dhgrp 14
set src-subnet 192.168.10.0 255.255.255.0
set dst-subnet 10.50.0.0 255.255.0.0
next
end
PFS mismatches will also cause Phase 2 failures. If one side has PFS enabled and the other doesn't, you'll get a negotiation error that looks similar to a selector mismatch. Enable it on both or disable it on both — pick a stance and be consistent across all your tunnels.
Root Cause 3: Dead Peer Detection Triggering
Dead Peer Detection (DPD) is a keepalive mechanism that lets each VPN peer verify the other is still reachable. When DPD doesn't receive a response after its configured retry limit, it tears down the IKE SA — and the tunnel with it. The problem is that DPD can trigger falsely. Intermittent packet loss on the underlay, a remote firewall under heavy CPU load that can't respond to probes in time, or an asymmetric routing change that breaks the return path for DPD probes — any of these can cause DPD to kill a tunnel that was otherwise carrying traffic just fine.
This is the root cause behind the classic "tunnel drops every 20 minutes" complaint. The tunnel establishes, works for a while, DPD kills it, it reconnects, and the cycle repeats. Tunnels with low background traffic — say, overnight with minimal user activity — are especially vulnerable because
on-idleDPD probes aggressively even when no user data is flowing, making marginal underlay conditions much more likely to trip the timeout.
How to Identify It
Check the VPN event logs from the CLI:
execute log filter category 1
execute log filter field action dpd
execute log display
Or navigate to Log & Report > Events > VPN Events in the GUI. You're looking for messages like:
DPD maximum retransmissions reached, action=hold
IKE SA TUN-SOLVENET deleted (reason: DPD timeout)
Review the current DPD settings in the Phase 1 config:
show vpn ipsec phase1-interface TUN-SOLVENET | grep dpd
Typical output:
set dpd on-idle
set dpd-retrycount 3
set dpd-retryinterval 20
How to Fix It
Before changing anything, confirm whether DPD is killing a healthy tunnel or a genuinely unreachable peer. Run a sustained ping across the tunnel from the FortiGate itself while watching the event logs:
execute ping-options source 192.168.10.1
execute ping 10.50.0.1
If traffic flows but DPD still fires, switch to
on-demandmode and give the retry parameters more headroom:
config vpn ipsec phase1-interface
edit "TUN-SOLVENET"
set dpd on-demand
set dpd-retrycount 5
set dpd-retryinterval 30
next
end
The
on-demandmode only probes when traffic needs to pass and the peer hasn't been heard from recently — far less aggressive than
on-idle, which fires regardless of whether any user data is flowing. Don't disable DPD entirely in production though. Without it, stale SAs from a remote peer that crashed and restarted can silently blackhole traffic for hours until the SA lifetime finally expires.
Root Cause 4: NAT-T Not Enabled
NAT Traversal (NAT-T) is required whenever one or both VPN peers are behind a NAT device. Standard IKE runs on UDP 500, and IPSec data traffic uses ESP — IP protocol 50, not TCP or UDP. NAT devices don't know how to track stateful connections for raw ESP because there are no port numbers to map. NAT-T solves this by wrapping ESP inside UDP port 4500, which any NAT device can handle like normal UDP traffic.
If one of your peers is behind a cloud provider NAT gateway, a home router doing PAT, or any device performing address translation, and NAT-T isn't configured, the tunnel won't carry data. What makes this especially deceptive is that Phase 1 may partially complete — the initial IKE exchange on UDP 500 can sometimes get through — but then the IPSec data plane never comes up because ESP packets are getting dropped or corrupted by the NAT device in the path.
How to Identify It
Check the IKE gateway details for the NAT status flag:
diagnose vpn ike gateway list name TUN-SOLVENET
Key lines to examine in the output:
vd: root/0
name: TUN-SOLVENET
version: 1
interface: wan1 3
addr: 192.168.1.1:500 -> 203.0.113.45:500
created: 142s ago
IKE SA: created 1/1 established 1/1 time 80/80/80 ms
IPsec SA: created 0/1 established 0/1 time 0/0/0 ms
direction: initiator
status: connecting
natt: disabled
IKE SA established but IPSec SA stuck at 0/1, combined with
natt: disabledwhen you know there's a NAT device in the path — that's the signature. The IKE debug will also show this explicitly:
ike 0:TUN-SOLVENET:1234: NAT detected, but NAT-T is disabled
ike 0:TUN-SOLVENET:1234: failed to negotiate NAT-T
How to Fix It
Enable NAT-T in the Phase 1 configuration:
config vpn ipsec phase1-interface
edit "TUN-SOLVENET"
set nattraversal enable
next
end
If both endpoints are FortiGates and you know definitively that NAT is in the path, use
forcedto skip auto-detection and start on UDP 4500 from the outset:
config vpn ipsec phase1-interface
edit "TUN-SOLVENET"
set nattraversal forced
next
end
Also verify that the device performing NAT has rules permitting both UDP 500 and UDP 4500 in both directions. UDP 500 alone isn't sufficient once NAT-T negotiation completes and the session shifts to port 4500. After making the change, flush and re-establish:
diagnose vpn ike gateway flush name TUN-SOLVENET
diagnose vpn tunnel flush TUN-SOLVENET
Root Cause 5: Route Missing for VPN Traffic
The tunnel can be fully established — Phase 1 up, Phase 2 up, SAs negotiated and green in the dashboard — and traffic still won't flow if there's no route telling the FortiGate to actually send packets into that tunnel. This catches people off guard because everything looks healthy on the VPN status page.
With route-based VPNs using virtual tunnel interfaces, which is the standard FortiGate deployment model, you need an explicit static route (or a routing protocol entry) pointing the remote subnet to the tunnel interface. Without it, traffic hits the default route and goes out the WAN toward the internet, where it obviously won't find a private RFC 1918 destination. This gap also surfaces after network changes: a new subnet gets added at the remote site, the remote admin updates their end, and nobody adds the corresponding route on the FortiGate side.
How to Identify It
Check the routing table for the remote subnet:
get router info routing-table all
Or query for the specific prefix you're trying to reach:
get router info routing-table details 10.50.0.0/24
If the output shows the default route absorbing your destination:
Routing entry for 0.0.0.0/0
Known via "static", distance 10, metric 0, best
* 203.0.113.1, via wan1
Traffic is matching the default route and heading to the internet. Confirm with a packet sniffer:
diagnose sniffer packet any "host 10.50.0.1" 4 10
If you see packets leaving on
wan1instead of the tunnel interface, the route is wrong or missing. The flow debug gives you the full picture:
diagnose debug flow filter addr 10.50.0.1
diagnose debug flow trace start 50
diagnose debug enable
You'll see exactly which route was matched and whether any policy accepted or dropped the traffic.
How to Fix It
Add a static route for the remote subnet pointing to the tunnel interface:
config router static
edit 0
set dst 10.50.0.0 255.255.0.0
set device "TUN-SOLVENET"
set comment "solvethenetwork.com remote site"
next
end
Verify the route is installed in the table:
get router info routing-table details 10.50.0.0/24
Expected output after adding the route:
Routing entry for 10.50.0.0/255.255.0.0
Known via "static", distance 10, metric 0, best
* directly connected, via TUN-SOLVENET
If you're using SD-WAN, verify the tunnel interface is a member of the correct SD-WAN zone and that SD-WAN rules aren't overriding your static route by steering VPN-destined traffic out a different member link. A misconfigured SD-WAN rule is a silent traffic thief.
Root Cause 6: Pre-Shared Key Mismatch
Simple but devastating. A PSK mismatch causes authentication to fail at Phase 1, and the tunnel never establishes at all. It happens during initial setup from a typo, a copy-paste that grabbed a trailing space or invisible newline character, or after a key rotation where one side gets the new PSK and the other doesn't. This one is easy to overlook because the symptoms look identical to a proposal mismatch — negotiation fails, the tunnel stays down.
How to Identify It
The IKE debug signature for a PSK mismatch is unmistakable:
ike 0:TUN-SOLVENET:1234: HASH mismatch
ike 0:TUN-SOLVENET:1234: authentication failed
ike 0:TUN-SOLVENET: negotiation failure
With IKEv2, you'll see:
ike 0:TUN-SOLVENET:1234: AUTHENTICATION_FAILED
ike 0:TUN-SOLVENET:1234: failed to authenticate peer
How to Fix It
Re-enter the PSK on both sides, confirming the value out-of-band with the remote admin. On the FortiGate CLI:
config vpn ipsec phase1-interface
edit "TUN-SOLVENET"
set psksecret YourActualSharedSecretHere
next
end
Be careful with special characters in the CLI. Characters like
!,
$, and
&can be interpreted by the shell and silently alter the key. When the PSK contains special characters, set it through the FortiGate GUI where you can paste the value directly without any shell escaping issues. After both sides are updated, flush the tunnel and re-test.
Root Cause 7: Firewall Policy Not Permitting VPN Traffic
Even with the tunnel up and the route correct, if there's no firewall policy permitting traffic between the local LAN zone and the VPN tunnel interface, everything gets silently dropped. FortiGate operates on an implicit deny-all — nothing passes unless explicitly allowed by policy. This trips up engineers who are used to platforms where a VPN tunnel implicitly carries all traffic once it's established.
How to Identify It
The flow debug is the fastest path to a definitive answer:
diagnose debug flow filter addr 192.168.10.5
diagnose debug flow filter addr 10.50.0.5
diagnose debug flow show function-name enable
diagnose debug flow show iprope enable
diagnose debug flow trace start 100
diagnose debug enable
Look for this in the output:
id=20085 trace_id=1 msg="find a route: flag=00000000 gw-192.168.10.5 via TUN-SOLVENET"
id=20085 trace_id=1 msg="Denied by forward policy check (policy 0)"
policy 0is the implicit deny. Traffic found the right route to the tunnel interface, but no policy allowed it to proceed.
How to Fix It
Add policies in both directions — outbound from LAN to VPN, and inbound from VPN back to LAN:
config firewall policy
edit 0
set name "LAN-to-VPN-SOLVENET"
set srcintf "internal"
set dstintf "TUN-SOLVENET"
set srcaddr "all"
set dstaddr "remote-subnet-solvenet"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
next
end
Don't forget the return direction. Traffic initiated from the remote network back toward your LAN also needs a policy from
TUN-SOLVENETto
internal, or you'll have a one-way tunnel that only works for connections you initiate.
Prevention
Most of these failures are entirely avoidable with good habits established at tunnel creation time. Document your VPN configurations fully — both sides — in a config management system or runbook. Record the Phase 1 and Phase 2 proposals, traffic selectors, DH groups, IKE version, NAT-T setting, and the PSK storage location. When something breaks at 2am, that documentation is the difference between a ten-minute fix and a two-hour war room call.
Set up alerting on tunnel state changes. FortiGate supports SNMP traps and syslog forwarding for VPN events. Forward these to your monitoring platform and create an alert for tunnel down events so you know the moment a link drops — not when users start filing tickets. FortiManager users can centralize this monitoring across every managed device from a single pane.
For business-critical tunnels, configure redundancy. A second tunnel over a backup ISP link with a higher administrative distance static route gives you automatic failover without manual intervention. Test that failover path regularly — don't assume it works just because it's configured. Simulate a primary tunnel failure during a maintenance window quarterly and confirm traffic switches over and recovers cleanly.
Standardize your VPN proposal sets across the organization. Pick a strong baseline — AES-256 with SHA-256, DH Group 14, IKEv2 — and use it everywhere you control both endpoints. When every internal tunnel uses the same proposal, mismatches become impossible between your own devices, and troubleshooting third-party tunnels is simpler because you know exactly what you're bringing to the negotiation.
Finally, run periodic VPN health checks. A simple monitoring script that pings across each tunnel every five minutes and logs the result will surface intermittent issues well before they become full outages. Pair that with structured VPN event log retention and you'll have the correlation data you need to tie tunnel drops to upstream events like ISP maintenance windows or BGP instability.
