425 Too Early
Usage
The 425 Too Early error is related to the time required to secure an HTTPS connection. When there is significant latency, the time required for TLS to create a secure connection becomes lengthy. One optimization is for a client to send data early in the process, before the secure connection is fully established.
If an intermediary is involved in the chain, the intermediary must include the Early-Data: 1 request header. An intermediary must not remove this header. This notifies the server the request was sent in early data and the client understands the 425 Too Early response.
Request
GET /tech-news HTTP/1.1
Host: example.com
Early-Data: 1
The original initiator of a request does not need to send this header. By sending data early, the client implies understanding of the consequences and handles the 425 Too Early response appropriately.
Sending early data is unfavorable in certain situations, and the server returns this error in response. The risk is the client request being replayed, leading to side effects compromising security.
When a client receives this status code, the request is retried automatically. After the handshake is complete and the secure connection is in place.
Example
The client requests a resource and the server responds with 425 Too Early, instructing the client to wait until the connection is fully established before retrying.
Request
GET /tech-news HTTP/1.1
Host: example.com
Content-Type: application/xml
Content-Length: 225
<Message includes early data>
Response
HTTP/1.1 425 Too Early
How to fix
Retry the request after the TLS handshake completes fully. The client waits for the secure connection to finish before re-sending. Most browsers and HTTP libraries handle this retry automatically.
Avoid sending non-idempotent requests (such as POST, PUT, or DELETE) in TLS 0-RTT early data. Only idempotent GET requests are safe for early data because replaying them has no side effects.
On the server side in nginx, the ssl_early_data directive controls 0-RTT behavior. Set ssl_early_data off; to reject all early data and eliminate this response entirely. When 0-RTT is enabled, pass the early-data signal to the backend with proxy_set_header Early-Data $ssl_early_data; so the application decides per-request whether to accept or reject early data.
Backend applications receiving the Early-Data: 1 header reject requests with side effects (account changes, payments, form submissions) by responding with 425. Safe read-only endpoints proceed normally.
Intermediaries forwarding early data from a client must preserve the Early-Data: 1 header. Removing the header prevents the origin server from detecting replay risk.
Code references
.NET
HttpStatusCode.TooEarly
Rust
http::StatusCode::TOO_EARLY
Rails
:too_early
Go
http.StatusTooEarly
Symfony
Response::HTTP_TOO_EARLY
Python3.9+
http.HTTPStatus.TOO_EARLY
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_TOO_EARLY
Angular
@angular/common/http/HttpStatusCode.TooEarly