This error occurs when you pass an unsupported or invalid encoding name to a Node.js readable stream's setEncoding() method. Common causes include typos in encoding names, using encodings that aren't built-in to Node.js, or specifying an encoding that doesn't match your data format.
Node.js readable streams use the setEncoding() method to automatically decode byte data into strings using a specified character encoding. The stream validates the encoding name against Node.js's supported encodings list (utf8, utf16le, ascii, hex, base64, base64url, latin1, and binary). When you pass an encoding that doesn't exist in this list or is misspelled, the stream throws an "Invalid encoding specified" error and stops processing data. This is a preventative validation: Node.js catches the error early rather than silently processing data with the wrong encoding, which could cause data corruption or silent failures downstream.
Node.js supports these encodings natively in streams:
- 'utf8' (or 'utf-8')
- 'utf16le' (or 'ucs2')
- 'ascii'
- 'hex'
- 'base64'
- 'base64url'
- 'latin1' (or 'binary')
Check your code to ensure you're using exactly one of these names:
const fs = require('fs');
// CORRECT: Use supported encoding
const stream = fs.createReadStream('file.txt', { encoding: 'utf8' });
// INCORRECT: Unsupported encoding
// const stream = fs.createReadStream('file.txt', { encoding: 'utf-8' });Note: 'utf-8' with a hyphen is NOT supported. Use 'utf8' without the hyphen.
If you're using setEncoding() on a readable stream, pass the correct encoding:
const fs = require('fs');
const stream = fs.createReadStream('input.txt');
// INCORRECT: Typo in encoding name
// stream.setEncoding('utf-8'); // Error: Invalid encoding
// CORRECT: Use the exact encoding name
stream.setEncoding('utf8'); // Works
stream.on('data', (chunk) => {
console.log('Received string:', chunk); // Already decoded as string
});For HTTP requests or other streams:
const http = require('http');
http.get('https://example.com', (res) => {
// CORRECT: Use valid encoding
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log('Received:', chunk);
});
});Wrap stream operations in error handling to catch encoding issues:
const fs = require('fs');
const stream = fs.createReadStream('file.txt');
// Validate encoding before use
const validEncodings = ['utf8', 'utf16le', 'ascii', 'hex', 'base64', 'latin1', 'binary'];
const requestedEncoding = getUserInput(); // From config, env, user input
if (!validEncodings.includes(requestedEncoding)) {
console.error(`Invalid encoding: ${requestedEncoding}`);
process.exit(1);
}
try {
stream.setEncoding(requestedEncoding);
} catch (error) {
console.error('Encoding error:', error.message);
// Fallback to utf8
stream.setEncoding('utf8');
}
stream.on('data', (chunk) => {
console.log('Received:', chunk);
});
stream.on('error', (error) => {
console.error('Stream error:', error);
});If the encoding comes from a config file, environment variable, or user input, validate it first:
const fs = require('fs');
function createReadStreamWithEncoding(filePath, encoding) {
const validEncodings = ['utf8', 'utf16le', 'ascii', 'hex', 'base64', 'latin1', 'binary', 'base64url'];
// Normalize and validate encoding
const normalizedEncoding = (encoding || 'utf8').toLowerCase().trim();
if (!validEncodings.includes(normalizedEncoding)) {
throw new Error(
`Invalid encoding '${encoding}'. Supported: ${validEncodings.join(', ')}`
);
}
const stream = fs.createReadStream(filePath);
stream.setEncoding(normalizedEncoding);
return stream;
}
// Safe usage
try {
const stream = createReadStreamWithEncoding('file.txt', process.env.FILE_ENCODING || 'utf8');
stream.on('data', (chunk) => console.log(chunk));
} catch (error) {
console.error('Failed to create stream:', error.message);
}Character Encoding Mismatch: Even with a valid encoding specified, the stream will fail silently if your data is encoded differently. For example, if a file is actually UTF-16LE encoded but you specify 'utf8', you'll get garbled characters. Always verify the actual encoding of your source data.
Binary Data and Streams: If you're working with binary data (images, audio, etc.), do not set an encoding—leave the stream as-is to receive Buffer objects. Setting an encoding is only appropriate for text data.
Readable-Stream Module: If you're using the 'readable-stream' npm package (a backport of Node.js streams), it supports the same encodings but may have different validation timing. Always check the module's documentation.
UTF-16 Variants: Node.js only supports UTF-16LE (little-endian), accessed via 'utf16le' or its alias 'ucs2'. UTF-16BE (big-endian) is not supported. If you need big-endian UTF-16, you'll need a third-party library or manual conversion.
Case Sensitivity: Encoding names are case-sensitive in some contexts. Always use lowercase ('utf8', not 'UTF8', 'Utf8', or 'UTF-8').
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: 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
Error: setuid EPERM (operation not permitted, user change failed)
setuid EPERM: Operation not permitted when changing process user