This error occurs when you pass an invalid compression level to Node.js zlib functions like createGzip() or createDeflate(). The compression level must be an integer between -1 (default) and 9 (maximum compression).
The "Compression level must be between -1 and 9" error is raised by Node.js's zlib module when you provide an invalid level option to compression functions. The zlib library, which Node.js uses for compression and decompression operations, only accepts specific integer values for the compression level parameter. Valid compression levels range from -1 to 9, where each value represents a different trade-off between compression speed and compression ratio. Using -1 tells zlib to use the default compression level (equivalent to level 6), 0 means no compression at all, 1 is the fastest compression with minimal size reduction, and 9 provides maximum compression but takes the longest time. Any value outside this range, including strings, floats, or undefined when not handled properly, will trigger this RangeError. This error commonly occurs when passing configuration options to gzip/deflate streams, compression middleware like Express's compression package, or when dynamically setting compression levels based on environment variables or user input without proper validation.
Check the value you're passing to the level option and ensure it's an integer between -1 and 9:
const zlib = require('zlib');
// Wrong - value outside valid range
const gzip = zlib.createGzip({ level: 10 }); // RangeError
// Correct - valid compression levels
const gzip1 = zlib.createGzip({ level: -1 }); // Default
const gzip2 = zlib.createGzip({ level: 0 }); // No compression
const gzip3 = zlib.createGzip({ level: 6 }); // Balanced
const gzip4 = zlib.createGzip({ level: 9 }); // Maximum compressionIf you're not sure what level to use, either omit the option entirely (uses default level 6) or explicitly use -1 for the default.
If you're reading the compression level from environment variables, ensure you parse it to an integer and validate the range:
const zlib = require('zlib');
// Wrong - environment variable is a string
const level = process.env.COMPRESSION_LEVEL; // "9" (string)
const gzip = zlib.createGzip({ level }); // May cause error
// Correct - parse and validate
const level = parseInt(process.env.COMPRESSION_LEVEL || '-1', 10);
if (level < -1 || level > 9) {
throw new Error('Invalid compression level. Must be between -1 and 9.');
}
const gzip = zlib.createGzip({ level });Always validate user input or configuration values before passing them to zlib functions.
Ensure you're passing options correctly to zlib functions. The level is a property of the options object:
const zlib = require('zlib');
// Wrong - passing level directly as second argument
const gzip = zlib.createGzip(level); // Incorrect syntax
// Correct - level is a property in options object
const gzip = zlib.createGzip({ level: 6 });
// For compression middleware
const compression = require('compression');
app.use(compression({
level: 6,
threshold: 0
}));Check the documentation for the specific function you're using to ensure correct option syntax.
If compression level is determined dynamically (from config, API, or calculations), add validation before creating streams:
function createCompression(userLevel) {
// Ensure level is a number
const level = Number(userLevel);
// Check if it's a valid number
if (isNaN(level)) {
throw new Error('Compression level must be a number');
}
// Ensure it's an integer in valid range
const validLevel = Math.max(-1, Math.min(9, Math.floor(level)));
return zlib.createGzip({ level: validLevel });
}
// Alternative: use a whitelist
const VALID_LEVELS = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function createCompressionSafe(level) {
if (!VALID_LEVELS.includes(level)) {
throw new Error(`Invalid compression level: ${level}. Must be between -1 and 9.`);
}
return zlib.createGzip({ level });
}This defensive approach prevents invalid values from reaching zlib functions.
Compression level meanings: Each level has specific characteristics:
- -1: Default (equivalent to 6), good balance of speed and compression
- 0: No compression (Z_NO_COMPRESSION), useful for already compressed data
- 1: Fastest compression (Z_BEST_SPEED), minimal CPU usage
- 2-8: Progressive trade-offs between speed and compression ratio
- 9: Maximum compression (Z_BEST_COMPRESSION), highest CPU usage
Performance considerations: Higher compression levels (7-9) provide diminishing returns in compression ratio while significantly increasing CPU time. For most web applications, levels 4-6 offer the best balance. Level 1 is excellent for real-time streaming where CPU is limited.
Express compression middleware: When using the compression package with Express, the level option defaults to -1. If you're setting it via environment variables, ensure proper parsing: level: parseInt(process.env.COMPRESSION_LEVEL, 10) || -1
Type coercion gotcha: JavaScript's type coercion doesn't help here. Passing a string like "6" may work in some contexts but could fail in strict validation. Always explicitly convert to integers.
Alternative: zlib constants: You can use named constants for readability: zlib.constants.Z_DEFAULT_COMPRESSION (-1), zlib.constants.Z_NO_COMPRESSION (0), zlib.constants.Z_BEST_SPEED (1), zlib.constants.Z_BEST_COMPRESSION (9).
Error: Listener already called (once event already fired)
EventEmitter listener already called with once()
Error: EACCES: permission denied, open '/root/file.txt'
EACCES: permission denied
Error: Invalid encoding specified (stream encoding not supported)
How to fix Invalid encoding error in Node.js readable streams
Error: EINVAL: invalid argument, open
EINVAL: invalid argument, open
TypeError: readableLength must be a positive integer (stream config)
TypeError: readableLength must be a positive integer in Node.js streams