fetch() does not decompress gzip responses
mattfysh opened ·
`fetch()` appears to return the raw gzip-compressed response body instead of transparently decompressing it.
Minimal repro:
```js const res = await fetch('https://httpbin.org/gzip')
console.log(res.status) console.log(res.headers.get('content-encoding')) console.log(await res.text()) ```
Observed:
```txt 200 gzip <binary gzip data> ```
Expected:
```txt 200 gzip { "gzipped": true, ... } ```
`Response.text()` should expose the decompressed body.
nickchomeyunsubscribedlast month on GitHub
- MA
Confirmed this still reproduces on **celld 0.6.2**, compared against **workerd 1.20261008.1** locally on Linux x86_64, with compatibility date `2026-10-08`.
I used the same Worker source in both runtimes, fetching a deterministic local HTTP fixture instead of httpbin. The fixture always returns a 55-byte gzip body with `Content-Encoding: gzip`; the uncompressed JSON is 35 bytes:
```json {"gzipped":true,"message":"hello"} ```
| API | workerd | celld 0.6.2 | | --- | --- | --- | | `res.text()` | Decoded JSON text | Raw gzip interpreted as text | | `res.json()` | Parses successfully | Throws `SyntaxError` | | `res.arrayBuffer()` | 35 decoded bytes | 55 compressed bytes | | First bytes | `7b 22` (`{"`) | `1f 8b` (gzip magic) |
Both return status 200 and retain `Content-Encoding: gzip`. No manual decompression or compatibility flags were used. Reproduced twice.
This affects consuming compressed upstream responses with `.text()` or `.json()`, including web-data extraction.