zlib.inflateSync()
Decompresses zlib-format (DEFLATE) data synchronously and returns the original bytes as a Buffer.
zlib.inflateSync(buffer[, options])- Added in Node.js v0.11.3
Parameters
| Parameter | Type | Description |
|---|---|---|
$buffer | Buffer | TypedArray | DataView | ArrayBuffer | string | zlib-format compressed data to expand. |
$optionsoptional | Object | zlib options: `windowBits`, `chunkSize`, `flush`, `finishFlush`, `dictionary`, `info` and `maxOutputLength`. |
Return value
BufferA Buffer holding the decompressed data. With `options.info` set to `true`, an object `{ buffer, engine }` is returned instead.
Errors
Throws `Z_DATA_ERROR` when the input is not a valid zlib stream or the Adler-32 checksum fails, `Z_NEED_DICT` when a required dictionary was not supplied, and `ERR_BUFFER_TOO_LARGE` when the output exceeds `maxOutputLength`.
Changelog
- PHP v5.11.0The `finishFlush` option is supported, allowing a truncated stream to be decoded up to the cut.
- PHP v8.0.0The `dictionary` option can be a `Uint8Array`.
- PHP v9.4.0The `dictionary` option can be an `ArrayBuffer`.
- PHP v14.5.0, v12.19.0The `maxOutputLength` option is supported.
zlib.inflateSync() reverses zlib.deflateSync(). It expects the RFC 1950 framing — a two-byte header, the DEFLATE payload, and an Adler-32 checksum — verifies that checksum, and returns the original bytes.
When to reach for it
Use it for data your own code deflated, and for the many file formats that embed zlib streams: PNG IDAT chunks, PDF FlateDecode objects, ZIP entries (those are raw DEFLATE, so inflateRawSync()), and Git loose objects. Because the call blocks, keep it to data already held in memory; use a stream for anything large or arriving incrementally.
What trips people up
- Format mismatch. Handing gzip data to
inflateSync()throwsZ_DATA_ERROR: incorrect header check. Gzip needsgunzipSync(); header-less DEFLATE needsinflateRawSync(). If you are sniffing, gzip starts with1f 8band zlib almost always with78. - Missing dictionary. Data compressed with a
dictionaryfails withZ_NEED_DICTunless you pass the identical dictionary back in. The dictionary is not stored in the stream. - Unbounded expansion. Compressed input from a network or a user upload can expand by orders of magnitude. Set
maxOutputLengthso an oversized result throwsERR_BUFFER_TOO_LARGEinstead of consuming memory.
Example
When to use it
- Read back a blob that was stored with deflateSync in a database column
- Decode a PDF FlateDecode object or a PNG IDAT chunk in a parser
- Expand a WebSocket permessage-deflate frame captured for debugging
- Assert in a test that a compression helper round-trips byte for byte
Frequently asked questions
How do I decompress deflate data in Node.js?
Call zlib.inflateSync(buffer) for zlib-framed data produced by deflateSync, or zlib.inflateRawSync(buffer) for header-less DEFLATE from deflateRawSync or a ZIP entry. Gzip data needs gunzipSync instead.
What causes Z_DATA_ERROR incorrect header check in inflateSync?
The buffer is not in zlib format — usually it is gzip data, which starts with 1f 8b and needs gunzipSync(), or raw DEFLATE with no header at all, which needs inflateRawSync().
What does Z_NEED_DICT mean?
The data was compressed with a preset dictionary that you have not supplied, so pass the identical bytes as options.dictionary to inflateSync. The dictionary is never embedded in the stream and must be shared out of band.
More examples
Pick the right decompressor from the header bytes
All three rows recover the same byte count from three different framings. The zlib check is the RFC 1950 rule: the first two bytes read as a big-endian integer must be divisible by 31. Raw DEFLATE has no header, so it is the fallback rather than something you can positively detect.
const zlib = require('node:zlib');
function decompress(buf) {
if (buf[0] === 0x1f && buf[1] === 0x8b) return zlib.gunzipSync(buf);
// zlib header: low nibble 8 (deflate) and the two bytes form a multiple of 31.
if ((buf[0] & 0x0f) === 0x08 && ((buf[0] << 8) + buf[1]) % 31 === 0) {
return zlib.inflateSync(buf);
}
return zlib.inflateRawSync(buf); // assume bare DEFLATE
}
const text = 'detect the framing '.repeat(20);
for (const [name, buf] of [
['gzip', zlib.gzipSync(text)],
['zlib', zlib.deflateSync(text)],
['raw ', zlib.deflateRawSync(text)]
]) {
console.log(name, '->', decompress(buf).length, 'bytes recovered');
}Inflating dictionary-compressed data
The first call fails with Z_NEED_DICT because the stream references bytes that only exist in the dictionary. Note the failure mode is an explicit error, not silent corruption — but it also means the dictionary is part of your data format and must be versioned alongside the stored blobs.
const zlib = require('node:zlib');
const dictionary = Buffer.from('status:active,role:member,region:');
const record = Buffer.from('status:active,role:member,region:eu-west-1');
const packed = zlib.deflateSync(record, { dictionary });
try {
zlib.inflateSync(packed);
} catch (err) {
console.log('without dictionary:', err.code); // Z_NEED_DICT
}
console.log('with dictionary:', zlib.inflateSync(packed, { dictionary }).toString());
Discussion