Objective
Determine why a TCP connection to a specific host and port fails by separating DNS resolution, routing, a service that is not listening, the local firewall, network ACLs, NAT, and asymmetric routing.
Prerequisites
- Destination hostname or IP address, exact TCP port, and expected application.
- A test source that represents the affected user or system.
- Access to the target server or its logs when possible.
- Knowledge of the intermediate firewalls, NAT rules, and ACLs.
- The exact test time so network and application logs can be correlated.
Step-by-step procedure
Confirm the destination and DNS resolution
If the application uses a hostname, first verify which IP address it resolves to from the affected workstation. Split-horizon DNS, an old record, or a stale cache can send the client to the wrong server even when the port is open elsewhere. Compare DNS answers from multiple networks when the service is published internally and externally.
Resolve-DnsName <FQDN>nslookup <FQDN>ipconfig /displaydns- The FQDN resolves to the address actually expected for this source.
Test the port from the actual source
Run Test-NetConnection from the workstation or server that experiences the problem and compare the result with another authorized source. If the test works from the LAN but not through a VPN, the path and policy difference immediately narrows the investigation. On multihomed systems, record the source address actually used.
Test-NetConnection <HOST> -Port <PORT> -InformationLevel Detailed- TcpTestSucceeded and the source and destination addresses provide a clear qualification of the failure.
Check that the service is listening on the server
On Windows, verify the listening socket and its owning PID. A network firewall cannot explain Connection refused when the application is stopped or listens only on localhost. Compare the application configuration with the port that is actually listening and verify the binding address.
Get-NetTCPConnection -State Listen | Where-Object LocalPort -eq <PORT>netstat -ano | findstr :<PORT>Get-Process -Id <PID>- The expected service is listening on the correct address and TCP port.
Test locally on the server
Test the loopback address and then the server LAN address from the server itself. If the application does not respond locally, do not change network devices yet: troubleshoot the service, its binding, any required certificate, and the host firewall first. If localhost works but the LAN address does not, the binding or host firewall becomes the priority.
Test-NetConnection 127.0.0.1 -Port <PORT>Test-NetConnection <SERVER-IP> -Port <PORT>- A local failure points to the application or host firewall rather than the network path.
Check the host firewall
Review Windows Defender Firewall or the operating-system firewall. Find an inbound rule that allows the correct program or port on the active network profile. Avoid disabling the firewall as a prolonged test; if necessary, create a narrowly scoped temporary rule and remove it after diagnosis.
Get-NetFirewallProfileGet-NetFirewallRule -Enabled True | Select DisplayName,Direction,Action,Profile- The port is allowed for the expected source and profile, or a local deny rule is identified.
Check intermediate routing, ACLs and NAT
On firewalls and routers, confirm that the real source, destination, and port match the intended rule. For a published service, verify the VIP or DNAT rule and the server return route. Correct destination NAT with a different return path can produce an incomplete TCP handshake. Also verify service objects, zones, and interfaces used by the security policy.
- The forward and return paths and the applicable security rule are consistent.
Observe the TCP handshake with a packet capture
A capture of SYN, SYN-ACK, ACK, and RST packets helps locate the failure. SYN with no reply indicates loss or filtering. SYN followed by RST means the host was reached but the service refused the connection. SYN and SYN-ACK without the final ACK usually indicates a blocked or asymmetric return path. On FortiGate, use a targeted sniffer; on the server, Wireshark or pktmon can provide the host-side view.
diagnose sniffer packet any 'host <CLIENT-IP> and host <SERVER-IP> and tcp port <PORT>' 4 30 l- The point at which the TCP handshake stops is identified.
Use a firewall flow debug if the capture is not enough
On FortiGate, a filtered debug flow can show the selected route, policy, and drop reason. Restrict the debug to the exact source, destination, and port, then disable it immediately after collection. If traffic is offloaded to an NPU, the trace can be incomplete; rely on packet capture and logs before changing acceleration settings.
diagnose debug resetdiagnose debug flow filter saddr <CLIENT-IP>diagnose debug flow filter daddr <SERVER-IP>diagnose debug flow filter dport <PORT>diagnose debug enablediagnose debug flow trace start 50diagnose debug flow trace stopdiagnose debug disablediagnose debug reset- The FortiOS policy and decision are known for the exact flow.
Retest the complete application
After the network correction, rerun Test-NetConnection and then test the real application client. An open TCP port does not guarantee that TLS, HTTP, SQL, or an application protocol succeeds. If the TCP handshake is now correct but the application still fails, inspect application logs, certificates, SNI, and authentication.
- The application service, not only the TCP port, works from the real source.
Validation
The procedure is validated when:
- The hostname resolves to the correct destination and forward and return routing are consistent.
- The service listens on the expected port and the host firewall allows the traffic.
- A complete TCP handshake is visible or Test-NetConnection succeeds.
- The real application client works after the correction.
Rollback
- Remove any temporary firewall rule created only for testing.
- Restore the previous ACL or NAT configuration if a network change does not produce the expected result.
- Re-enable any protection disabled temporarily and document the actual root cause.
Troubleshooting / common errors
- TcpTestSucceeded=False with Connection refused: verify the service and binding before changing the network firewall.
- Timeout with SYN visible on the client but not on the server: investigate intermediate filtering or incorrect routing.
- SYN-ACK visible on the server but absent on the client: investigate the return path or NAT.
- TCP works but the application fails: continue with TLS, protocol, or application-level troubleshooting.
- The test works by IP but not by hostname: return to DNS, SNI, and the resolved destination instead of opening the firewall further.