The short answer
Accept-Encoding: gzip, deflate, br, zstd is a request header in which the client says: "I can decompress a response body encoded with gzip, deflate, Brotli, or Zstandard — pick whichever you like, or send it uncompressed." The server chooses at most one of them, compresses the body, and names its choice in the Content-Encoding response header. If it compresses nothing, it simply omits Content-Encoding.
The header does not request compression of the request itself, it does not describe character encodings (that is charset in Content-Type), and it has nothing to do with Accept, which lists media types such as application/json. The full grammar is on the Accept-Encoding header reference; this page is the quick decoder.
Each token, decoded
| Token | Meaning | Notes |
|---|---|---|
gzip | gzip format (RFC 1952): DEFLATE data with a header and CRC-32 | Universally supported. See gzip. |
x-gzip | Legacy alias of gzip | Recipients should treat it as gzip. |
deflate | zlib format (RFC 1950) wrapping DEFLATE data | Historically ambiguous; some servers sent raw DEFLATE. See deflate. |
br | Brotli (RFC 7932) | Browsers advertise it only over HTTPS. See Brotli. |
zstd | Zstandard (RFC 8878) | Advertised by current Chrome, Edge and Firefox. See Zstandard. |
compress | Unix compress (LZW) | Obsolete; no modern browser advertises it. |
identity | No encoding | Acceptable by default unless explicitly refused. |
* | Any coding not otherwise listed | Mostly used with q=0 to refuse everything else. |
Common header strings and what they mean
Accept-Encoding: gzip, deflate
The client accepts gzip or zlib-wrapped deflate. This is what many HTTP libraries send when they have no Brotli decoder available (for example Python requests without a Brotli package installed). Servers almost always answer with gzip.
Accept-Encoding: gzip, deflate, br
Adds Brotli. This has been the browser default over HTTPS for years and is still what you see from clients without Zstandard support. A server that supports Brotli will normally prefer br for text responses.
Accept-Encoding: gzip, deflate, br, zstd
Adds Zstandard. Chrome and Edge send this from version 123 and Firefox from version 126 on secure connections. Most servers still answer with br or gzip unless they, or the CDN in front of them, have Zstandard enabled.
Accept-Encoding: br;q=1.0, gzip;q=0.8, *;q=0.1
An explicit preference order: Brotli most preferred, then gzip, then anything else. Without q-values every listed coding has q=1, and the order of the list carries no meaning — the server applies its own preference among equally weighted codings.
Accept-Encoding: gzip;q=0, deflate;q=0, identity;q=1
The client refuses gzip and deflate and asks for an uncompressed body. Useful when debugging or when a downstream component cannot handle compressed data.
Accept-Encoding: identity
"Send it uncompressed." Clients use this when they need raw bytes — for example to compute byte ranges or to measure the uncompressed size. Servers should honour it by sending no Content-Encoding.
Accept-Encoding: *
Any coding is fine, including identity. Valid, but rare; most servers treat it like a request that accepts gzip.
An empty Accept-Encoding: header
Per RFC 9110, an empty value means the client wants no content coding at all — only identity is acceptable.
No Accept-Encoding header at all
Formally, any coding is then considered acceptable. In practice, well-behaved servers send an uncompressed response to a client that did not ask for compression, because they cannot be sure the client can decode it.
Values that are not codings
Strings such as Accept-Encoding: none, Accept-Encoding: application/json or Accept-Encoding: utf-8 are mistakes. Servers ignore unknown tokens, so the practical effect is usually an uncompressed response. Media types belong in Accept and character sets in the charset parameter of Content-Type.
What browsers and HTTP clients send by default
| Client | Default behaviour |
|---|---|
| Chrome, Edge (123+) | gzip, deflate, br, zstd over HTTPS; set automatically, cannot be changed from page JavaScript |
| Firefox (126+) | gzip, deflate, br, zstd over HTTPS |
| Safari | gzip, deflate, br over HTTPS; Zstandard support has lagged the other engines, so check the release notes of the version you target |
| curl | No Accept-Encoding unless you pass --compressed, which advertises every encoding the build supports and decompresses the output |
Go net/http | Adds Accept-Encoding: gzip automatically and transparently decompresses, unless you set the header yourself or disable compression on the Transport |
Python requests | gzip, deflate; recent urllib3 versions add br and zstd when the corresponding decoder packages are installed |
| OkHttp (Android / JVM) | Adds gzip transparently and decompresses, unless you set the header yourself |
.NET HttpClient | Nothing by default; set AutomaticDecompression on the handler to advertise and decode gzip, deflate and Brotli |
In a browser, Accept-Encoding is a forbidden request header name: fetch() and XMLHttpRequest silently ignore attempts to set it. The browser always decompresses responses before your script sees them. More detail per engine is on the browser compatibility page.
HTTP_ACCEPT_ENCODING and header-name constants
HTTP_ACCEPT_ENCODING is the same request header seen through the CGI convention, where request headers are exposed as upper-case variables prefixed with HTTP_ and hyphens become underscores. You meet it in PHP ($_SERVER['HTTP_ACCEPT_ENCODING']), in IIS URL Rewrite conditions ({HTTP_ACCEPT_ENCODING}), and in WSGI environments (environ['HTTP_ACCEPT_ENCODING']). It contains exactly the string the client sent.
<?php
$ae = $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '';
// e.g. "gzip, deflate, br, zstd"
if (preg_match('/\bgzip\b/i', $ae)) {
// client accepts gzip
}
Frameworks also provide constants for the header name so you do not have to type the string: HttpHeaders.ACCEPT_ENCODING in Spring and Guava, HttpHeaderNames.ACCEPT_ENCODING in Netty, and HeaderNames.AcceptEncoding in ASP.NET Core. They all resolve to "Accept-Encoding". Note that a naive substring check like the PHP example above ignores q-values; to honour gzip;q=0 you need a real parser, as described on the header reference.
What the server sends back
Whatever the request said, check the response, not the request, to see what happened:
$ curl -s -o /dev/null -D - -H "Accept-Encoding: gzip, deflate, br, zstd" https://example.com/
HTTP/2 200
content-type: text/html; charset=utf-8
content-encoding: br
vary: Accept-Encoding
content-encoding: br means the server picked Brotli from the list; vary: Accept-Encoding tells caches that the body depends on the request header (see Vary: Accept-Encoding). If Content-Encoding is absent, the body is uncompressed — the troubleshooting guide walks through why that happens.
Frequently asked questions
What does Accept-Encoding: gzip, deflate, br, zstd mean?
The client can decompress responses encoded with gzip, deflate (zlib), Brotli (br) or Zstandard (zstd). The server picks one, or none, and reports its choice in the Content-Encoding response header.
What is br in Accept-Encoding?
br is the content-coding token for Brotli, a compression format standardised in RFC 7932. Browsers only advertise it on HTTPS connections.
Does the order of values in Accept-Encoding matter?
No. Without q-values all listed codings are equally acceptable and the server applies its own preference. To express a preference, use q-values such as br;q=1, gzip;q=0.8.
What does Accept-Encoding: identity mean?
It asks for an uncompressed response. identity means no transformation; servers should respond without a Content-Encoding header.
Can the Accept-Encoding value be an asterisk?
Yes. * matches any coding not listed elsewhere in the header. Accept-Encoding: * accepts anything, while gzip, *;q=0 accepts gzip only and refuses even identity.
What is the default Accept-Encoding?
There is no protocol-level default. Browsers set it automatically (for example gzip, deflate, br, zstd in current Chrome and Firefox over HTTPS). Libraries vary: Go and OkHttp add gzip, Python requests sends gzip, deflate, curl sends nothing unless you use --compressed.
What is HTTP_ACCEPT_ENCODING?
It is the Accept-Encoding request header as exposed by CGI-style environments such as PHP $_SERVER, IIS server variables and WSGI. Its value is the raw header string sent by the client.