TLS Early Data Trades Handshake Latency for Replay Exposure
A returning client can possess enough state from a prior TLS 1.3 connection to send application data alongside its first handshake flight. That removes a round-trip from the critical path for eligible traffic, but it also changes a security property that applications often treat as implicit: encrypted transport no longer means that a request can appear only once across connections.
TLS 1.3 early data, commonly called 0-RTT, is protected using keys derived from a pre-shared key associated with an earlier session or an externally provisioned PSK. The server has not yet contributed fresh handshake state when those bytes are transmitted. As a result, early data has weaker replay properties than ordinary application data sent after the handshake.
The operational boundary therefore moves upward. TLS can protect early bytes from passive disclosure and modification under the negotiated construction, but an application that accepts state-changing requests in that phase must account for duplicated delivery.
Fresh server state arrives too late to bind the first flight
Ordinary TLS 1.3 application traffic is derived from a handshake that incorporates fresh server input. Early data is different. A client offering a suitable PSK can derive early traffic keys before receiving the server’s new ServerHello, which is precisely what makes transmission in the first flight possible.
That latency reduction prevents the first application bytes from depending on fresh per-connection server state. TLS 1.3 consequently does not provide cross-connection non-replay guarantees for 0-RTT data. An attacker able to capture a valid early-data flight can attempt to present it again under conditions where a server accepts the associated PSK and early data.
This is not equivalent to forging a new request. The attacker does not gain arbitrary plaintext construction from replay alone. The risk is duplication of a request the legitimate client already produced. For operations such as a balance transfer, purchase submission, one-time action, or mutation with external side effects, duplication can be sufficient to create a security or integrity failure.
TLS acceptance and application safety are separate decisions
At the TLS layer, a server either accepts the offered early data or does not. Acceptance depends on protocol conditions tied to the PSK and negotiated parameters. It does not establish that every application request carried in those records is safe to execute more than once.
That distinction is especially important for HTTP. A TLS terminator can accept 0-RTT because the connection satisfies transport requirements while the origin has resource-specific knowledge that a particular request must not be processed under replay exposure.
HTTP defines the Early-Data request field to carry that state across intermediary hops. A gateway forwarding a request that might have been processed from early data can mark it so the origin retains the relevant context even after TLS termination. The signal prevents the transport boundary from erasing information needed for the application decision.
For a request that cannot safely be processed under replay exposure, HTTP also defines status code 425 Too Early. A retry after that response is sent after the handshake rather than as early data. This converts a request from the weaker 0-RTT context into ordinary post-handshake processing without requiring the origin to reject the entire TLS connection.
Method labels do not fully describe replay consequences
HTTP method semantics provide a useful first filter, but they are not a complete replay policy. A nominally safe request can still trigger application-specific side effects, expensive computation, audit events, rate consumption, cache population, or interaction with a backend whose behavior is not purely observational.
Conversely, an application can sometimes make a mutation tolerant of duplicate delivery by binding it to a stable operation identifier and enforcing uniqueness at the authoritative state transition. That is an application property, not a property created by 0-RTT.
Replay tolerance must therefore be evaluated at the operation boundary where effects become durable. A proxy rule based only on method names can miss side effects hidden behind a GET, while a blanket ban on every non-GET request can discard valid performance opportunities without expressing the actual invariant.
Distributed anti-replay state changes the availability trade-off
TLS 1.3 describes server-side measures that can reduce replay exposure, including recording information associated with accepted early data. In a single process, maintaining such state can be conceptually direct. A fleet complicates the boundary.
If multiple edge instances can accept the same resumption material, replay detection may require coordinated state, constrained ticket scope, or routing properties that keep acceptance decisions consistent. Coordination adds storage, synchronization, failure handling, and availability costs. Loose coordination can leave separate instances able to accept the same captured flight.
A strict anti-replay design can also create false rejection during failover or partition events. The engineering choice is not simply security enabled versus security disabled; it is a decision about where replay state lives, how long it remains authoritative, and what happens when that state cannot be consulted.
For many state-changing HTTP operations, refusing early processing is simpler than building globally consistent replay tracking. The latency optimization can remain enabled for traffic whose duplicate execution is acceptable while sensitive operations fall back to a completed handshake.
Retry behavior can duplicate effects without an attacker
Replay exposure is not limited to deliberate adversarial retransmission. Early data can be rejected by the server, after which a client may resend application data once the handshake completes. TLS specifications leave retransmission decisions to the application because automatic resending can violate application assumptions.
This creates a second boundary around acknowledgment. A client that cannot tell whether an early request reached application processing must not equate transport-level rejection with proof that no effect occurred. Systems that retry mutations need an idempotency mechanism whose scope reaches the durable operation, rather than relying on connection state as a uniqueness guarantee.
The same issue appears when gateways retry on behalf of clients. HTTP’s early-data signaling and 425 response coordinate that behavior, but they do not make arbitrary operations idempotent. The origin remains the component with enough context to decide whether duplicate execution is acceptable.
Early data is a scoped optimization, not a default transport property
TLS 1.3 does not require applications to use early data. A deployment can support session resumption while declining 0-RTT entirely, preserving most of the authentication and key-establishment benefits of resumed sessions without admitting pre-handshake application bytes.
Where 0-RTT is enabled, its value is highest when request semantics and replay policy are explicit across every hop. TLS termination, load balancing, retries, origin processing, and durable state changes all participate in that decision. If any layer drops the early-data context or assumes encryption implies uniqueness, the latency optimization crosses a trust boundary without carrying the security condition that made it safe.
The central trade-off is narrow but consequential: early data removes handshake latency by acting before fresh server state can bind the request to one connection. Systems that accept that optimization must supply replay tolerance or replay control at the layer where duplicated effects matter.