Network & Connectivity
Work through these in order before diving deeper. Most connectivity failures resolve at step 1, 2, or 4.
- 1 Ping the host — confirms basic IP reachability. If ping fails, the problem is at the network layer, not the FIX layer. Check routing and DNS resolution first.
-
2
Telnet or netcat to the FIX port —
telnet fix-host.exchange.com 9001ornc -zv fix-host.exchange.com 9001. A blank connection means TCP is up. "Connection refused" means the port is closed or filtered. - 3 Check your firewall rules — outbound traffic to the exchange's FIX port must be allowed. Most exchanges use ports in the 7000–9999 range; confirm the exact port in your exchange spec.
- 4 Verify SenderCompID / TargetCompID — wrong comp IDs cause the exchange to reject the Logon silently or with a Logout. Confirm the exact string values (case-sensitive) with your exchange onboarding contact.
-
5
Check the BeginString — connecting with
FIX.4.2to aFIX.4.4session will be rejected. Confirm the FIX version in your exchange spec and in your session config. - 6 Review your application logs for the raw Logon message — is the message actually being sent? If no outbound Logon appears in logs, the TCP connection may be failing silently before FIX begins.
- 7 Check session hours — most exchanges restrict FIX session availability to trading hours (e.g., 06:00–22:00 ET). Connecting outside the window will be refused at the TCP or FIX layer.
- 8 Confirm the environment — UAT and production use different hostnames, ports, and comp IDs. A common mistake is connecting a production system to a UAT endpoint (or vice versa).
FIX runs over a persistent TCP connection. Connectivity problems fall into two distinct layers — and knowing which layer is failing tells you where to look.
- Connection refused — port is closed
- Connection timed out — host unreachable or firewall dropped
- Connection reset (RST) — server closed unexpectedly
- SSL/TLS handshake failure
- DNS resolution failure
- Logon rejected — wrong comp IDs or credentials
- Logout received immediately after Logon
- Wrong BeginString
- Heartbeat timeout → disconnect
- Session not available (outside hours)
telnet to the FIX port connects successfully but your application cannot establish a FIX session, the problem is in the FIX session layer — not the network. Look at Logon / Logout message content, not firewalls.
Each TCP error has a distinct meaning and a different resolution path.
| Error | Meaning | What to check |
|---|---|---|
| Connection refused | Target host is reachable, but nothing is listening on that port | Confirm the port number in your exchange spec. The FIX gateway may not be running, or session hours may have ended. |
| Connection timed out | SYN packet sent but no SYN-ACK received within the OS timeout (~75s) | Firewall is dropping your packets silently. Check outbound allow rules for the exchange's IP range and port. Also confirm the hostname resolves to the correct IP. |
| Connection reset (RST) | TCP connection was established, then the remote host sent a RST | Exchange server is actively rejecting after accepting — often a TLS mismatch, IP whitelist failure, or the FIX gateway restarted mid-session. |
| ETIMEDOUT / read timeout | TCP connection is up but no data received within the read timeout window | Heartbeat interval may be misconfigured. Check that HeartBtInt (108) in your Logon matches what the exchange expects. Also check for packet loss mid-session. |
| ECONNRESET (mid-session) | Exchange closed the connection unexpectedly after session was established | Usually follows a Logout message — check logs. Common causes: missed heartbeat, bad sequence number, invalid message, session timeout. |
When your application opens a TCP connection, the FIX session protocol expects a Logon (35=A) to be sent immediately. Most exchanges enforce a tight window — often 10–30 seconds — before closing the connection.
Once a session is established, the FIX heartbeat mechanism serves as the connectivity health check. Understanding it lets you diagnose mid-session disconnects.
| Message | 35= | Purpose & when sent |
|---|---|---|
| Heartbeat | 0 | Sent every HeartBtInt seconds when no other messages have been sent. Confirms the session is alive. |
| TestRequest | 1 | Sent when no message has been received from the counterparty for HeartBtInt + tolerance seconds. Expects a Heartbeat in response containing the same TestReqID (112). |
| Heartbeat (response) | 0 | Response to TestRequest. Contains TestReqID (112) echoing the value from the TestRequest. If this is not received, the session is considered dead and a Logout / disconnect follows. |
35=1 (TestRequest) and note whether a matching 35=0 response follows within a few seconds. If TestRequests are being sent repeatedly with no response, the exchange end is not receiving your messages — check for network partitions, one-way packet loss, or a crashed gateway process on their side.
FIX sessions use persistent long-lived TCP connections. Stateful firewalls that time out idle connections are a common source of mid-session drops, especially in low-volume environments.
| Exchange / Venue | Typical Port Range | Notes |
|---|---|---|
| NYSE Pillar (equities) | 9001–9010 | Ports vary by session type (order, drop copy). Confirm in the NYSE Pillar Gateway spec. |
| NASDAQ | 7000–7999 | Separate ports for UAT and production. Some sessions use TLS on a different port. |
| Cboe BZX / EDGX | 9400–9500 | Titanium spec lists exact ports per market and session type. |
| IEX | 9000+ | Confirm per environment in the IEX FIX specification. |
HeartBtInt × 3, or enable TCP keepalives on the socket.
IP whitelisting: Most exchanges require your outbound IP addresses to be whitelisted on their firewall. Submit your NAT/egress IPs to the exchange during onboarding. If you rotate IPs (e.g., cloud environments with dynamic IPs), you will need to update the whitelist each time.
Many exchanges now require TLS for FIX sessions, especially in production. TLS failures at the handshake stage look identical to a TCP RST from the application's perspective — the connection is dropped before any FIX bytes are exchanged.
| TLS Error | Likely Cause |
|---|---|
| SSL handshake timed out | Port expects plain TCP but your client is sending a TLS ClientHello. Or firewall is blocking. Try connecting without TLS first. |
| Certificate verify failed | Exchange's server certificate is signed by a CA not in your trust store, or the hostname in the cert doesn't match what you're connecting to. Add the exchange's root CA to your trust store. |
| Handshake failure (alert 40) | No shared cipher suite. Exchange may require TLS 1.2+ or a specific cipher. Check whether your client is offering compatible cipher suites. |
| No certificate / Client cert required | Exchange requires mutual TLS (mTLS). You must present a client certificate. Obtain this from the exchange during onboarding. |
| Certificate expired | Either your client cert or the exchange's server cert has expired. Check both. Exchange certs rotate on a schedule — subscribe to their infrastructure notices. |
98=0 (None) in the Logon message. TLS operates at the transport layer — it's invisible to FIX. Setting 98=1 (DES) or other values will cause a Logon rejection.
High latency or intermittent packet loss causes heartbeat misses and unexpected session drops, even when basic connectivity looks fine. Measure before adjusting heartbeat intervals.
| Symptom | Likely cause | Resolution |
|---|---|---|
| Repeated TestRequests, then disconnect | Packet loss or high latency causing heartbeat misses | Increase HeartBtInt (108) to give more tolerance, or fix the underlying network issue |
| Messages received out of order in logs | TCP reordering (should not affect delivery — TCP guarantees order) | Usually a logging artifact. Check if timestamps on logs are from message receipt vs. application processing. |
| Latency spikes at market open/close | Network congestion at peak traffic times | Consider dedicated/leased line connectivity. Shared internet paths are not suitable for latency-sensitive FIX. |
| Periodic disconnects every ~60 minutes | Stateful firewall or NAT device timing out idle connection | Enable TCP keepalives, reduce HeartBtInt, or increase firewall idle timeout |
UAT and production environments almost always have different hostnames, ports, comp IDs, and sometimes different FIX versions. Misconfiguration when promoting from UAT to production is a frequent source of connectivity failures.
| Parameter | UAT | Production |
|---|---|---|
| Hostname | uat-fix.exchange.com | fix.exchange.com |
| Port | 9001 (separate range) | 9001 (same port, different host) |
| SenderCompID | FIRMID_UAT | FIRMID |
| TargetCompID | EXCHANGE_UAT | EXCHANGE |
| TLS required | Often optional | Usually required |
| IP whitelist | Broader (dev IPs allowed) | Strict (only production IPs) |
FIRMID_UAT or TARGET_TEST. The exchange will refuse the Logon — often with no error message, just a Logout or RST. Always diff your UAT and production config files before going live.
When application-level logs are inconclusive, a packet capture shows exactly what bytes are on the wire — including whether TCP packets are being sent, received, dropped, or retransmitted.
What to look for in the capture:
- ✓ SYN → SYN-ACK → ACK — three-way handshake completed. TCP connection is up.
- ✗ SYN → (no reply) — firewall is dropping your SYN packets. The host is either unreachable or a firewall is silently filtering.
- ✗ SYN → RST — port is closed on the target. Nothing is listening, or the host is actively rejecting the connection.
- ! Retransmits (e.g., [TCP Retransmission]) — packets are being sent but acknowledgment is not arriving. Indicates packet loss in one direction.
- ! RST after data — exchange is closing the connection after receiving your Logon. Check for TLS mismatch, rejected comp IDs, or IP whitelist failure.
Run through this before connecting to any new FIX environment. A 5-minute check here prevents hours of debugging later.