Back to HTTP Headers

Expect general request

Lets a client ask the server to check conditions before the client sends a large request body — avoiding wasted bandwidth on rejected requests.

What it does

Expect lets a client ask the server to verify conditions before the client sends a potentially large request body. The only defined value is 100-continue — it tells the server: "I want to send you a big body, but check my headers first and tell me if you'll accept it before I bother uploading."

This avoids wasting bandwidth uploading a 500MB file to a server that's going to reject the request due to an invalid auth token, wrong content type, or exceeded size limit.

Syntax

Expect: 100-continue

There is only one defined value. Any other value causes the server to return 417 Expectation Failed.

How it works

Without Expect:

1. Client sends headers + 500MB body
2. Server checks headers → rejects (401 Unauthorized)
3. 500MB was uploaded for nothing

With Expect: 100-continue:

1. Client sends headers only (with Expect: 100-continue)
2. Server checks headers → OK
3. Server sends 100 Continue
4. Client sends 500MB body
5. Server processes and responds

Or:

1. Client sends headers only
2. Server checks headers → 401 Unauthorized (before body is sent)
3. Client abandons the upload immediately

The bandwidth saving can be enormous for large file uploads or bulk API operations.

The 100 Continue response

100 Continue is an informational status code (1xx) sent by the server to tell the client "your headers look fine, go ahead and send the body." It's sent before the final response.

If the server doesn't send 100 Continue within a reasonable timeout (typically 1-5 seconds), most HTTP clients send the body anyway. The Expect mechanism is advisory, not blocking.

When to use it

Large file uploads. Sending Expect: 100-continue with the initial request headers lets the server validate auth, content-type, size limits, and other conditions before the upload begins.

API bulk operations. If you're sending a large JSON payload (thousands of records), getting a fast rejection on bad headers before uploading is valuable.

Low-bandwidth or metered connections. The bandwidth saving is more significant when upload bandwidth is expensive or limited.

Most HTTP client libraries have an option to enable Expect: 100-continue automatically above a configurable body size threshold.

Server handling

Servers can respond to Expect: 100-continue three ways:

  1. Send 100 Continue — headers are acceptable, proceed with body
  2. Send an error immediately (401, 403, 413, etc.) — reject without waiting for body
  3. Ignore it and wait — many simpler servers don't explicitly send 100; the client eventually times out and sends the body anyway

The HTTP spec requires servers to send 100 Continue if they intend to process the request, but many don't implement this explicitly and instead rely on client timeouts.

Common mistakes and gotchas

Setting Expect on small request bodies. The round trip to receive 100 Continue adds latency. For small payloads (a few KB), this overhead outweighs the bandwidth benefit. Only use it for genuinely large bodies.

Not handling the timeout case. Clients must handle the case where no 100 Continue arrives — either retry without Expect or send the body after a timeout. Most mature HTTP libraries handle this automatically.

Using Expect on GET or DELETE. Expect: 100-continue only makes sense on requests with a body (POST, PUT, PATCH). On bodyless methods, it's meaningless.

Real-world examples

Large file upload with pre-validation:

PUT /api/uploads/large-dataset.csv HTTP/1.1
Host: api.example.com
Authorization: Bearer mytoken
Content-Type: text/csv
Content-Length: 524288000
Expect: 100-continue

HTTP/1.1 100 Continue

<524MB of CSV data>

HTTP/1.1 201 Created

Server rejecting before body is sent:

POST /api/import HTTP/1.1
Content-Type: application/json
Content-Length: 1048576
Expect: 100-continue
Authorization: Bearer expired-token

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api", error="invalid_token"

The 1MB body is never sent.

FAQ

Do browsers use Expect: 100-continue?

Rarely. Browsers generally don't send Expect: 100-continue for form uploads — they just upload the body directly. The feature is more relevant for programmatic HTTP clients (curl, API SDKs, upload libraries) where you have more control over the request flow.

Does curl support Expect: 100-continue?

Yes — curl automatically adds Expect: 100-continue on POST/PUT requests above a certain body size (1024 bytes by default). You can disable it with --no-expect if it's causing issues with servers that don't handle 100 Continue gracefully.

What's the difference between 100 Continue and 200 OK?

100 Continue is an interim response — the server is saying "keep going, I'll give you a real response when you finish." 200 OK is the final response after the full request is processed. After sending 100, the server still sends a final 200, 201, 400, etc. once the body arrives and is processed.

Fun fact

The 100 Continue mechanism was added to HTTP/1.1 specifically to fix a real performance problem with early web servers: clients uploading large files to servers that would reject them (wrong auth, wrong content type) had no way to know until the full upload completed. A university research group documented wasted bandwidth in the gigabytes per day across enterprise proxy caches. Expect: 100-continue was the spec response. Despite being in HTTP since 1997, it's still not universally implemented by servers — a testament to how long it takes for edge-case protocol features to reach full adoption.