How HTTP Works
4xx · Client error
< HTTP/1.1 417 Expectation Failed

417 Expectation Failed: Expect 100-continue

417 Expectation Failed means a server or proxy rejected your Expect header, usually Expect: 100-continue. Learn the causes and fixes for curl, .NET and Squid.

Reviewed 3 min readintermediate4 sourcesTry itMarkdown
Cacheable
Only with explicit freshness
Retry?
No: drop the Expect header
Usually sent by
Origin or proxy
Spec
RFC 9110 §15.5.18
On this page

TL;DR: 417 means something on the path rejected your Expect header. Nearly every real case is Expect: 100-continue meeting a proxy or server that does not support it. Remove the header (curl -H 'Expect:', ExpectContinue = false) and the request goes through.

What Expect: 100-continue does

For a large upload, the client can ask permission first: it sends the headers with Expect: 100-continue, then waits. A server that is happy answers 100 Continue and the client sends the body. A server that would reject the request (auth failure, too large) can answer with a final status code immediately, so the client never wastes bandwidth on the body. See 100.

POST /upload HTTP/1.1
Host: api.example.com
Content-Length: 52428800
Expect: 100-continue

HTTP/1.1 100 Continue

RFC 9110 §10.1.1: a server that receives an Expect value it does not understand or cannot meet should respond with 417. A server that receives Expect: 100-continue from an HTTP/1.0 client should ignore it, and a proxy receiving it must either answer immediately (a final status or its own 100 Continue) or forward it to the next hop, which is where mismatched proxies go wrong.

POST /upload HTTP/1.1
Host: api.example.com
Content-Length: 52428800
Expect: 100-continue

HTTP/1.1 417 Expectation Failed
Content-Length: 0

Where it comes from

  • curl. It adds Expect: 100-continue automatically on POST/PUT when the body is large (the cutoff has changed between curl versions), and for any chunked upload. A proxy that chokes on the header produces 417 for exactly these uploads, while small requests succeed, which is why the failure looks size-dependent.
  • .NET. HttpWebRequest sent Expect: 100-continue by default. A common failure was through an old Squid or an HTTP/1.0 gateway.
  • Squid and other forward proxies. Older Squid versions answer 417 for Expect: 100-continue unless configured to tolerate it. Upgrading or removing the header solves it.
  • Reverse proxies and WAFs. A proxy that terminates the request, then forwards HTTP/1.0 or buffers differently, may refuse the expectation.
  • Application servers. Some embedded servers and older CGI-style gateways never implemented 100-continue and reject any Expect.

To confirm who is rejecting: send the same request directly to the origin (bypassing the proxy), and compare Server/Via headers on the 417.

Fix it

Remove the header on the client:

# curl: an empty value deletes the header
curl -X POST -H 'Expect:' -T bigfile.bin https://api.example.com/upload
// .NET Framework
System.Net.ServicePointManager.Expect100Continue = false;

// HttpClient
client.DefaultRequestHeaders.ExpectContinue = false;
# python-requests never sends Expect: 100-continue, so a 417 here
# means you set the header yourself (or a library did)
// Go's net/http only sends Expect if you set it yourself:
// req.Header.Set("Expect", "100-continue")
// and then waits ExpectContinueTimeout (default 1s in DefaultTransport).

If you operate the server, support it properly where possible: an application that can validate headers (auth, Content-Length vs limits) before reading the body should reply 100 Continue or a final 4xx early. Proxies in front must forward the interim response. If you cannot, ignoring Expect: 100-continue entirely is allowed by RFC 9110, and the client sends the body after its timeout.

Reproduce it

curl -v -X POST -H 'Expect: 100-continue' -d @bigfile.bin https://api.example.com/upload
# > Expect: 100-continue
# < HTTP/1.1 417 Expectation Failed

curl -v -X POST -H 'Expect:' -d @bigfile.bin https://api.example.com/upload
# no Expect header, no 417

Frequently asked questions

What does 417 Expectation Failed mean?

The request contained an Expect header with an expectation the server, or a proxy on the path, cannot meet. In practice that is almost always Expect: 100-continue sent to a server or proxy that does not implement it.

How do I fix 417 in curl?

curl adds Expect: 100-continue itself for larger POST and PUT bodies. Suppress it with -H "Expect:", which removes the header, and the request is sent normally.

How do I fix 417 in .NET?

Set ServicePointManager.Expect100Continue = false for HttpWebRequest, or HttpClient.DefaultRequestHeaders.ExpectContinue = false. A 417 from .NET clients generally comes from an HTTP/1.0 proxy or a gateway that rejects the header.

Why does curl pause for one second before sending my POST?

curl sent Expect: 100-continue and is waiting for 100 Continue before transmitting the body. If the server never answers it, curl gives up waiting after one second and sends the body anyway. Removing the Expect header removes the delay.

Is 417 the same as 412 or 428?

No. 412 is a failed If-* precondition on the resource and 428 means the server requires a conditional request. 417 is about the Expect header, which concerns how the request itself is sent.

Sources

  1. MDN Web Docs: 417 Expectation Faileddeveloper.mozilla.org
  2. RFC 9110 Section 15.5.18: 417 Expectation Failedrfc-editor.org
  3. RFC 9110 Section 10.1.1: Expectrfc-editor.org
  4. MDN Web Docs: Expect headerdeveloper.mozilla.org

Keep going

Browse /search