# 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.

Source: https://howhttpworks.com/status-codes/417
Last reviewed: 2026-10-04

> **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](https://howhttpworks.com/status-codes/100).

```http
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.

```http
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:

```bash
# curl: an empty value deletes the header
curl -X POST -H 'Expect:' -T bigfile.bin https://api.example.com/upload
```

```csharp
// .NET Framework
System.Net.ServicePointManager.Expect100Continue = false;

// HttpClient
client.DefaultRequestHeaders.ExpectContinue = false;
```

```python
# python-requests never sends Expect: 100-continue, so a 417 here
# means you set the header yourself (or a library did)
```

```go
// 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

```bash
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
```

## Related

- [100 Continue](https://howhttpworks.com/status-codes/100): the interim response the client is waiting for.
- [411 Length Required](https://howhttpworks.com/status-codes/411): another upload refusal.
- [413 Content Too Large](https://howhttpworks.com/status-codes/413): reject the body early with this instead of reading it.
- [412 Precondition Failed](https://howhttpworks.com/status-codes/412): failed If-* conditions.
- [Expect header](https://howhttpworks.com/headers/expect): how to stop curl sending Expect: 100-continue.
