oven-sh/bun · error · TypeError
CompressionFailed
CompressionFailed
Error message
CompressionFailed
What it means
Compressing a buffered fetch request body failed at the codec level (src/http/compress_body.rs — construction sites at :145, :168, :208, :221, :226, :238). This is the automatic request-body compression behind `fetch(url, { compress: ... })`: gzip/deflate go through libdeflate with a zlib streaming fallback, brotli/zstd use one-shot encoders. Any encoder init failure, bad zlib return code, zstd compress_bound error, or failed one-shot encode maps to CompressionFailed and fails the request.
Source
Thrown at src/http/error.rs:4
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
pub enum Error {
#[error("CompressionFailed")]
CompressionFailed,
#[error("Aborted")]
Aborted,
#[error("WriteFailed")]
WriteFailed,
#[error("HTTP2RefusedStream")]
HTTP2RefusedStream,
#[error("HTTP2ContentLengthMismatch")]
HTTP2ContentLengthMismatch,
#[error("HTTP2FrameSizeError")]
HTTP2FrameSizeError,
#[error("HTTP2ProtocolError")]
HTTP2ProtocolError,
#[error("HTTP2FlowControlError")]
HTTP2FlowControlError,
#[error("HTTP2EnhanceYourCalm")]
HTTP2EnhanceYourCalm,
#[error("HTTP2HeaderListTooLarge")]View on GitHub (pinned to 8c5296ac45)
Solutions
- Drop the custom `level` and use `compress: true` or `compress: 'gzip'` — defaults are pre-validated per codec (deflate 6, brotli 6, zstd 3).
- Clamp the level yourself per encoding: deflate/gzip 0-9, brotli 0-11, zstd 1-22 minus extreme values.
- For multi-GB bodies, split the upload or compress manually with Bun.gzip/Bun.deflateSync in chunks instead of request-body compression.
- Catch the fetch rejection and retry uncompressed if compression is optional for the server.
Example fix
// before
await fetch(url, { method: 'POST', body: bigJson, compress: { type: 'gzip', level: 11 } }); // zlib max is 9
// after
await fetch(url, { method: 'POST', body: bigJson, compress: { type: 'gzip', level: Math.min(9, level) } });
// or simply
await fetch(url, { method: 'POST', body: bigJson, compress: true }); Defensive patterns
Strategy: try-catch
Validate before calling
const LEVELS = { gzip: [0, 9], deflate: [0, 9], br: [0, 11], zstd: [1, 22] };
function validCompress(opt) {
if (opt === true || typeof opt === 'string') return true;
const enc = opt.type ?? opt.encoding;
const [lo, hi] = LEVELS[enc];
return opt.level === undefined || (opt.level >= lo && opt.level <= hi);
}
if (!validCompress(opts.compress)) opts.compress = true; // fall back to defaults Try / catch
try {
const res = await fetch(url, { method: 'POST', body, compress });
} catch (err) {
if (String(err.message).includes('CompressionFailed')) {
return fetch(url, { method: 'POST', body }); // retry uncompressed
}
throw err;
} Prevention
- Use `compress: true` — per-codec defaults are pre-validated
- Clamp custom levels per encoding (deflate max 9, not brotli's 11)
- For multi-GB bodies, compress manually or chunk instead of using request-body compression
When it happens
Trigger: Calling fetch with `compress: { encoding: 'gzip'|'deflate'|'br'|'zstd', level }` where level is outside the codec's accepted range (zlib path clamps to 0..=9, but a wildly invalid value or mismatched encoding/level combos can still fail encoder creation), or the input triggers a compress_bound overflow (multi-GB zstd bodies). Buffered (string/Bytes) bodies only — streams skip compression.
Common situations: Porting Node code with numeric compression levels tuned per codec (brotli 11 passed where zlib 9 max); sending very large (>2-4GB) JSON payloads with compress on; version skew where a codec level enum changed meaning.
Related errors
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/78a40a24a9f2b7cb.
Report an issue: GitHub.