A TCP socket can remain in the established state on one host after the peer has become unreachable or has lost all connection state. No contradiction exists in that state: TCP endpoints maintain local protocol state, and a silent network failure does not automatically deliver evidence that the peer is gone.
This creates a boundary between connection state and peer liveness. An established socket records what the local TCP implementation currently knows about a byte-stream association. It is not a continuously refreshed assertion that the remote process, host, route, and intervening network are all operational.
Silence carries no failure signal
Consider two hosts with an established TCP connection and no data in flight. If one host loses power, the other host does not necessarily receive a packet announcing the event. The surviving endpoint can therefore retain its established connection state.
The same property appears when connectivity disappears without a clean TCP close. A failed link, routing disruption, stateful middlebox change, or abrupt host loss can remove the usable path while leaving the local endpoint with no immediate protocol event to process.
A graceful close is different. When a peer sends a FIN and that segment reaches the local endpoint, TCP has explicit evidence that the peer has closed its sending side. A reset provides another explicit signal. Silent disappearance supplies neither.
This distinction makes “connected” a local protocol-state description rather than a general-purpose health predicate.
Failure detection starts when an operation needs evidence
Once the application sends data, TCP has work whose delivery requires acknowledgement. If acknowledgements do not arrive, retransmission logic can eventually report failure to the application according to the host’s TCP behavior and configured limits.
That detection is not instantaneous. TCP is designed to tolerate packet loss and delay, so one missing acknowledgement cannot establish that the peer is dead. Retransmission consumes time precisely because temporary loss must remain distinguishable from a failed path.
A read has a different boundary. A blocking read on an otherwise idle connection cannot infer peer loss merely from the absence of bytes. Silence may be valid application behavior. Unless another mechanism supplies a deadline or probe, no incoming data and no incoming failure signal can look identical.
Application code that treats an open file descriptor as proof of remote availability therefore assigns stronger semantics than TCP provides.
Keepalive probes add transport-level evidence
TCP keepalive can probe an otherwise idle connection when the operating system and socket configuration enable it. After an idle interval, the stack sends probes and can close the connection if the peer fails to respond after the configured policy is exhausted.
Keepalive changes failure-detection behavior, but it does not turn TCP into continuous health monitoring. Detection latency depends on the configured idle interval, probe spacing, probe count, operating-system semantics, and network conditions. Defaults can also differ across systems.
The mechanism is intentionally scoped to transport reachability. A peer TCP stack can answer transport traffic while the application above it is overloaded, deadlocked, or otherwise unable to provide useful service. A successful transport probe therefore establishes less than successful application work.
Keepalive is most precise when its role is stated narrowly: it can create traffic that gives TCP an opportunity to detect an otherwise silent broken connection.
Application heartbeats test a different boundary
An application protocol can define its own ping and response messages. Such a heartbeat traverses more of the software path than a transport keepalive when the remote application itself must parse the request and produce the response.
That broader path can be useful, but its semantics depend entirely on the protocol. A heartbeat handled by a lightweight event loop may succeed even while a separate worker pool is saturated. A response can confirm that one code path is active without proving that every operation is available.
Heartbeat intervals also create load and timing choices. Short intervals produce faster evidence at the cost of more traffic and processing. Long intervals reduce routine work but leave a larger interval in which failed peers can remain locally plausible.
The important design property is not the presence of a heartbeat label. It is the exact work required to generate a valid response and the deadline attached to that exchange.
Deadlines bound waiting even without a diagnosis
A deadline provides a different guarantee from a liveness probe. It does not need to classify the peer as failed. It only limits how long a particular operation may wait.
For a request-response protocol over TCP, a request deadline can expire while the underlying connection remains open. The caller then has a bounded outcome for that operation even if the transport has not declared the connection dead.
This separation is valuable because transport failure detection and application latency budgets answer different questions. TCP may continue retransmitting because recovery is still plausible at the transport layer, while the application may already have exceeded the time in which the result remains useful.
Closing a connection after an application deadline is a policy choice, not an automatic TCP requirement. Some protocols can safely continue using the stream after a timed operation; others cannot, especially when cancellation leaves response framing or request ordering ambiguous.
Connection pools amplify stale-state exposure
A pool can retain idle TCP connections specifically so later operations avoid establishing new ones. That reuse also means a connection can sit silent while its remote path disappears.
The next borrower may receive a socket that still appears established locally. Failure then surfaces only when the borrower performs I/O or when a prior liveness mechanism has already invalidated the entry.
A pool can probe connections before reuse, cap idle lifetime, rely on transport keepalive, or accept first-use failure and retry where operation semantics permit. Each policy moves detection cost to a different point. None can derive remote liveness from local socket state alone.
Retry also requires separate reasoning. If a write fails after some bytes were accepted locally, the caller may not know whether the peer processed the corresponding operation before connectivity vanished. Repeating a non-idempotent operation can therefore create duplicate effects unless the application protocol supplies a suitable deduplication mechanism.
Middleboxes create another state boundary
TCP state can exist not only at the two endpoints but also in network devices that track flows. A NAT or firewall may expire an idle mapping before either endpoint discards its socket state.
Later packets can then encounter a path whose intermediary state no longer matches endpoint expectations. Depending on the network, traffic may be dropped, rejected, or mapped differently. Endpoint keepalive or application heartbeat traffic can keep some stateful paths active, but that behavior depends on the devices and policies involved.
This is another reason an established endpoint socket cannot represent the state of the complete path. The local kernel has no universal, synchronous view of every forwarding and state-tracking element between peers.
Liveness semantics belong to the layer that needs them
TCP supplies an ordered byte stream with transport-level mechanisms for delivery, acknowledgement, retransmission, closure, and reset. It cannot guarantee that an idle connection continuously reflects remote application health.
Systems that need bounded failure detection add explicit evidence at the appropriate layer: transport keepalive for idle connection probing, protocol heartbeats for application-path checks, operation deadlines for bounded waiting, and retry rules for recoverable failures.
These mechanisms overlap in observable effects but not in meaning. A keepalive response, heartbeat response, completed request, and unexpired local socket each establish different facts.
Treating those facts as interchangeable produces fragile failure handling. A half-open connection is the clearest counterexample: local TCP state can remain valid according to all evidence received so far while the remote side is already unusable. The gap persists until some mechanism generates new evidence.