HTTP 100 Continue

HTTP 100 Continue is an informational response that tells the client: your request headers are acceptable and you may now send the request body. It is used with the Expect: 100-continue request header as a bandwidth optimization for large uploads — the client checks whether the server will accept the request before transmitting a multi-megabyte body that might be rejected outright. If the server sends 100, the client sends the body. If the server sends an error (401, 403, 413), the client abandons the body without wasting bandwidth.

HTTP 100 quick reference →

Quick reference

Code100
NameContinue
Category1xx Informational
SpecificationRFC 9110 §15.2.1
Triggered byExpect: 100-continue request header
PurposeAvoid sending large bodies that the server will reject
Cacheable?No — informational responses are never cached

The Expect: 100-continue flow

The full exchange for a large upload using Expect: 100-continue:

POST /api/videos/upload HTTP/1.1
Host: api.example.com
Content-Type: video/mp4
Content-Length: 524288000
Authorization: Bearer token
Expect: 100-continue

[client pauses, waits for server response]

HTTP/1.1 100 Continue

[client now sends 500MB video body]

HTTP/1.1 201 Created
Location: /api/videos/vid_abc123

The flow without body delivery on rejection:

POST /api/videos/upload HTTP/1.1
Content-Length: 524288000
Authorization: Bearer free-tier-token
Expect: 100-continue

[client pauses]

HTTP/1.1 413 Content Too Large
{"error": "file_too_large", "max_bytes": 104857600}

[client abandons body, did not send 500MB over the network]

In the second scenario, the client saved 500MB of outbound bandwidth by checking first. On a 100Mbps connection, that is about 40 seconds of upload time saved.

Which HTTP client libraries use Expect: 100-continue

Many HTTP client libraries automatically add Expect: 100-continue for POST and PUT requests above a size threshold. This happens transparently unless the developer explicitly suppresses it.

curl: Automatically adds Expect: 100-continue for request bodies over 1024 bytes. Disable with -H 'Expect:':

curl -X POST -H 'Expect:' -d @large_file.json https://api.example.com/upload

Python requests: Does not add Expect by default. Some versions of the underlying urllib3 may add it for large bodies. Explicitly set or suppress:

import requests
response = requests.post(url, data=body, headers={'Expect': '100-continue'})

Java (Apache HttpClient 4.x): Adds Expect: 100-continue by default for entity-enclosed requests. Configure with RequestConfig.expectContinueEnabled(false) to disable.

Go net/http: Does not add Expect by default. Can be set manually in request headers.

AWS SDK: The AWS SDK adds Expect: 100-continue for S3 PUT operations to prevent uploading large files to buckets or paths that would be rejected for permission reasons.

Server-side handling

RFC 9110 specifies that a server receiving a request with Expect: 100-continue should either send 100 Continue (if it will process the request) or send an error response (if it would reject the request based on headers alone, before seeing the body).

Servers are not required to send 100 before receiving the body — they may proceed to receive the body without sending 100 and only respond after processing. Some servers ignore the Expect header entirely and just receive the body. The client must handle both cases: send 100 if received, or send the body after a timeout if no 100 arrives.

nginx: Handles Expect: 100-continue natively for proxied connections. nginx sends 100 to the client and forwards the request body to the upstream. The proxy_expect_100_continue directive controls this behavior:

location /upload/ {
    proxy_pass http://upload_backend;
    proxy_expect_100_continue on;  # default: on
    client_max_body_size 500m;
}

Express.js (Node.js):

const http = require('http');
const server = http.createServer((req, res) => {
    // Express handles Expect: 100-continue automatically
    // via Node.js HTTP server's checkContinue event
});

// For explicit control:
server.on('checkContinue', (req, res) => {
    // Check authorization, content-type, content-length here
    if (req.headers['content-length'] > 500 * 1024 * 1024) {
        res.writeHead(413);
        return res.end('File too large');
    }
    // Send 100 to proceed:
    res.writeContinue();
    // Then handle the request as normal:
    app(req, res);
});

What happens if the client does not receive 100

RFC 9110 defines client behavior when the server does not send 100 within a reasonable time: the client should proceed to send the body anyway. Clients typically wait 1–5 seconds after sending headers before giving up on the 100 response and sending the body directly. This fallback ensures compatibility with servers that ignore the Expect header.

If the server sends an error (417 Expectation Failed) instead of 100, the client should interpret this as: the server does not support the Expect mechanism. The client should retry without the Expect header (sending the body directly).

For non-interactive clients (background jobs, API clients), a simple retry strategy: on receiving 417, disable Expect: 100-continue and retry the full request with the body included from the start.

100 vs 417 vs other 1xx codes

CodeMeaningClient action
100ContinueSend the request body now
417Expectation FailedRetry without Expect header (server does not support 100-continue)
401UnauthorizedAuthenticate, then retry with body
413Content Too LargeDo not send body; reduce size and retry
103Early HintsPreload resources listed in Link headers while waiting for final response

Frequently asked questions

What does HTTP 100 mean?

The server received the request headers and confirmed they are acceptable. The client should proceed to send the request body. This response is only sent when the client included Expect: 100-continue in its request headers.

Do browsers use Expect: 100-continue?

Generally no. Browsers do not add Expect: 100-continue for form submissions or fetch() requests. The mechanism is primarily used by programmatic HTTP clients (curl, language SDKs, API clients) making large uploads. Some browser file upload implementations may use it, but it is uncommon.

What is the timeout before a client sends the body without 100?

RFC 9110 does not specify a timeout. In practice, curl uses a 1-second default (--expect100-timeout configures it). Java Apache HttpClient defaults to 3 seconds. Python urllib3 uses a short timeout before proceeding. Clients that implement the mechanism should document their timeout.

Is Expect: 100-continue supported in HTTP/2?

HTTP/2 does not use the Expect mechanism. HTTP/2 multiplexes streams and does not have the same request-header-then-body two-phase model that makes 100-continue useful in HTTP/1.1. HTTP/2 clients should not send Expect: 100-continue.

Related guides

HTTP 417 Expectation Failed · HTTP 413 Content Too Large · HTTP 103 Early Hints

Standards reference

Definitions from the IANA HTTP Status Code Registry and RFC 9110 §15.2.1. Human-readable guidance by ErrorLookup. · HTTP 100 quick reference →