Skip to main content
4xx Client Error

425 Too Early

The server is unwilling to risk processing a request that might be replayed.

Meaning & Description

The HTTP 425 Too Early status code is used in conjunction with TLS Early Data (0-RTT). It indicates that the server is unwilling to risk processing a request because it might be a replay attack. When a client resumes a TLS connection, it can send data on the first round trip (0-RTT). However, this data is vulnerable to being captured and replayed by an attacker. If a request modifies state, the server should reject it with 425 to force the client to retry over a fully secure, established connection.

Common Causes

  • The client sent a state-changing POST request using TLS Early Data.
  • The server is configured to reject all 0-RTT traffic for sensitive API endpoints.
  • A proxy between the client and server forwarded a 0-RTT request that the backend deemed unsafe.

How to fix a 425 error

  1. If you are writing a client, ensure your HTTP library handles 425 by automatically retrying the request without the Early-Data header.
  2. If you are configuring a server, ensure idempotency for endpoints accepting Early Data, or configure the reverse proxy to automatically return 425 for non-GET requests.
  3. Check for the presence of the `Early-Data: 1` header in incoming requests.
  4. Disable 0-RTT on the server if your application architecture cannot handle replay attacks safely.

Browser & SEO Behaviour

Browser Behavior

Modern browsers (like Chrome and Firefox) that support TLS 1.3 0-RTT will transparently handle a 425 response by automatically retrying the request once the TLS handshake is fully complete, invisible to the user.

SEO Impact

No SEO impact. Search engine crawlers typically do not use 0-RTT for state-changing operations, and they automatically retry on 425.

CDN Behavior

CDNs like Cloudflare support 0-RTT. They can be configured to automatically reject non-GET requests in Early Data with a 425, or forward the `Early-Data` header to the origin server to make the decision.

Code Examples

HTTP
POST /api/transfer HTTP/1.1
Host: api.example.com
Early-Data: 1
Content-Type: application/json

{"amount": 1000}
Node.js (Express)
app.post('/api/transfer', (req, res) => {
  if (req.headers['early-data'] === '1') {
    return res.status(425).send("Too Early: Request might be replayed");
  }
  // Process transfer safely
  res.send("Transfer complete");
});
Python (FastAPI)
@app.post("/api/checkout")
def checkout(request: Request):
    if request.headers.get("Early-Data") == "1":
        raise HTTPException(status_code=425, detail="Too Early")
    return {"status": "Processing"}
Go (net/http)
func checkoutHandler(w http.ResponseWriter, r *http.Request) {
    if r.Header.Get("Early-Data") == "1" && r.Method != "GET" {
        http.Error(w, "Too Early", 425)
        return
    }
    w.WriteHeader(http.StatusOK)
}
C# (ASP.NET Core)
[HttpPost("checkout")]
public IActionResult Checkout() {
    if (Request.Headers.TryGetValue("Early-Data", out var earlyData) && earlyData == "1") {
        return StatusCode(425, "Too Early to process safely.");
    }
    return Ok();
}
curl
curl -X POST https://api.example.com/data \
  -H "Early-Data: 1" \
  -d '{"action":"buy"}' \
  -i

Raw HTTP Response Example

HTTP Response
HTTP/1.1 425 Too Early
Content-Type: text/plain
Content-Length: 46

Too Early: TLS 0-RTT replay protection active.

Real-world Examples

Cloudflare: Allows enabling 0-RTT in dashboard settings, but automatically protects against replay attacks by blocking unsafe HTTP methods during Early Data.
Nginx: Can be configured to read the $ssl_early_data variable and return 425 for unsafe requests.
HAProxy: Supports TLS 1.3 0-RTT and allows configuration to reject early data via ACLs returning HTTP 425.

Frequently Asked Questions

What is TLS 1.3 Early Data (0-RTT)?

0-RTT (Zero Round Trip Time) is a feature of TLS 1.3 that allows a client to send HTTP request data along with the initial TLS handshake, saving connection time for returning visitors.

Why is 0-RTT dangerous for POST requests?

Because 0-RTT data can be intercepted by an attacker and re-sent (replayed) to the server. If the request was a money transfer, a replay attack could cause the transfer to happen twice.

Do users see a 425 error screen?

No. Browsers are programmed to intercept a 425 response and automatically re-send the request securely once the connection is fully established. It happens instantly in the background.

How does a server know a request is Early Data?

The proxy or web server decrypting the TLS connection typically injects an 'Early-Data: 1' HTTP header before passing the request to the backend application.

Should I disable 0-RTT entirely?

Not necessarily. 0-RTT is excellent for speeding up GET requests (like loading images or HTML). You only need to protect state-changing endpoints (POST, PUT, DELETE).

Did You Know?

The 425 status code was introduced specifically to address the security trade-offs of TLS 1.3's performance optimizations.

A replay attack doesn't require the attacker to decrypt the payload; they just copy the encrypted bytes and hurl them at the server again.

Prior to RFC 8470, 425 was unofficially proposed as 'Unordered Collection' in WebDAV, but that draft was abandoned.

Developer Tips

  • Rely on your reverse proxy (Nginx, HAProxy, Cloudflare) to handle 0-RTT and 425 responses so your application code doesn't have to worry about TLS specifics.
  • If you must handle it in application logic, look for the 'Early-Data: 1' header and return 425 immediately for any non-idempotent operation.
  • Ensure your APIs are properly RESTful. If a GET request changes state, 0-RTT could cause unintended side effects during replay.

Interview Questions

These are questions you might face in a backend or API design interview that touch on HTTP 425.

What problem does the HTTP 425 Too Early status code solve?

It mitigates replay attacks introduced by TLS 1.3 0-RTT (Early Data). It tells the client that the server refuses to execute a potentially unsafe, state-changing request until the connection is fully secure.

How should an HTTP client behave when receiving a 425 status code?

The client should automatically re-attempt the exact same request after the TLS handshake has completed, without prompting the user.

Is it safe to accept 0-RTT Early Data for GET requests?

Generally yes, assuming the GET request is strictly idempotent and read-only, as REST principles dictate. Replaying a safe read operation has no adverse side effects.

Common Interview Mistakes

  • Confusing 'Too Early' with rate limiting ('Too Many Requests' - 429) or premature execution.
  • Failing to associate 425 with TLS 1.3, 0-RTT, and replay attacks.
  • Assuming the client must display an error message to the user upon receiving a 425.