You created a virtual IP (VIP) to publish an internal HTTPS server. The firewall policy looks correct, but external clients still time out. Before changing the policy, find out where the TCP handshake stops. A packet that never reaches the WAN interface requires a different fix from one that reaches the server but gets no reply.
Scope: IPv4 on FortiOS 7.6, with TCP port 443 on both sides. The addresses are illustrative. This scenario was not run on a live firewall.
Lab scenario
| Item | Example value |
|---|---|
| External test client | 198.51.100.25 |
| VIP external address and port | 203.0.113.10:443 |
| Mapped server and port | 10.20.20.50:443 |
| FortiGate ingress | wan1 |
| Server-side interface | port3 |
Start with a client outside the FortiGate. An internal client using the same public hostname exercises a different path, covered in the hairpin NAT section.
1. Confirm the SYN reaches the WAN interface
Capture on the expected WAN interface and start a fresh HTTPS connection from the external client. If an upstream device translates the destination first, use the address as FortiGate receives it.
diagnose sniffer packet wan1 'host 198.51.100.25 and host 203.0.113.10 and tcp port 443' 4 20
If no SYN arrives, check public DNS, routing to the public address, and any upstream port forwarding. If the SYN reaches wan1, move on to the VIP and policy.
2. Check the VIP and firewall policy destination
Verify the VIP ingress match, external IP, TCP protocol, external port, mapped IP, and mapped port. If there is a source restriction, confirm it allows the actual client address.
| NAT mode | What to check |
|---|---|
| Central NAT disabled | The WAN-to-server firewall policy references the VIP object as its destination. |
| Central NAT enabled | Enable the VIP under DNAT & Virtual IPs. The firewall policy uses an address object for the mapped server, 10.20.20.50 in this example. Check Central SNAT separately if the design requires source translation. |
Troubleshoot within the existing NAT mode. Changing the mode affects how FortiGate applies NAT and should be handled as a separate change.
3. Use Debug Flow to separate a DNAT miss from a policy deny
Run the trace in the relevant VDOM. Coordinate with other administrators before changing shared debug state. Filter on the original destination seen on ingress and reproduce the connection once.
diagnose debug flow filter clear
diagnose debug flow filter saddr 198.51.100.25
diagnose debug flow filter daddr 203.0.113.10
diagnose debug flow filter proto 6
diagnose debug flow filter dport 443
diagnose debug flow show function-name enable
diagnose debug flow trace start 20
diagnose debug enable
Follow one trace_id. Look for translation to 10.20.20.50:443, a route toward port3, and the policy decision. If you see policy 0, first determine whether DNAT occurred. If translation is missing, revisit the VIP match. If DNAT is correct, inspect the forward policy’s interface pair, destination, source, service, and schedule. Exact output varies by build.
Stop the trace as soon as the test is complete.
diagnose debug flow trace stop
diagnose debug disable
diagnose debug flow filter clear
For help reading route and policy decisions, see FortiGate Debug Flow Explained.
4. Verify the server sees the SYN and replies
Capture on the server-side interface using the mapped address and port. This filter can still match if source NAT changes the client address. On a busy server, correlate the results with the test timestamp or narrow the filter once you know the translated source.
diagnose sniffer packet port3 'host 10.20.20.50 and tcp port 443' 4 20
| What you observe | Where to look next |
|---|---|
| SYN on wan1, no translated SYN on port3 | Check VIP matching, route selection, policy, and capture visibility. |
| Translated SYN leaves port3, no SYN-ACK returns | Check the server listener, host firewall, and the server gateway’s return path. |
| SYN-ACK returns on port3, but the client never gets it | Trace the reply on both interfaces and check session translation and the upstream path. |
| TCP handshake completes, but HTTPS fails | Check TLS, the certificate hostname, and the application. |
5. Works from the internet but fails inside? Check hairpin NAT
Resolve the public hostname from the internal client. If it returns the private server address, troubleshoot the private path. If it returns the public VIP address and traffic reaches FortiGate, trace the internal client’s IP to the public VIP.
If the client and server sit behind the same FortiGate interface, the policy can be port3 to port3. Confirm that the VIP matches the internal ingress and capture the source address seen by the server. On the same subnet, a server may reply directly to the client if the original source is preserved, bypassing the firewall that translated the destination. Fortinet documents a Central NAT hairpin example that applies source translation without an explicit Central SNAT rule for that flow. Check your session or capture before adding a rule.
Verify the fix from both locations. Open the same hostname externally and internally. Confirm the TCP handshake and load the HTTPS application. Record the original destination, translated destination, matched policy, and observed reply path.
Fortinet references
Central DNAT · Central SNAT · VIP port forwarding troubleshooting · Hairpin NAT with Central NAT