This error occurs when you specify a character encoding that Node.js does not natively support, such as "utf-16" or a misspelled encoding name. Node.js supports specific encodings like utf8, utf16le, ascii, and base64.
The "unsupported encoding" error is thrown when Node.js encounters a character encoding it doesn't recognize or support. This typically happens when using Buffer methods, fs operations, or stream encoding with an invalid encoding parameter. Node.js has a fixed set of supported encodings: utf8 (the default), ascii, utf16le (also called ucs2), base64, latin1 (binary), and hex. Importantly, Node.js does NOT support "utf-16" - it requires the specific variant "utf16le" (UTF-16 Little Endian). The error can also occur from simple typos like "UTF-8" (uppercase) instead of "utf8", though Node.js is usually case-insensitive for well-known encodings. This is a common issue when working with international text, file I/O, or when migrating code from other platforms that use different encoding names. Understanding which encodings Node.js supports and how to convert between them is essential for text processing applications.
Node.js does not support "utf-16" as an encoding name. Instead, use "utf16le" (UTF-16 Little Endian):
// Wrong - will throw unsupported encoding error
const buffer = Buffer.from('Hello', 'utf-16');
// Correct - use utf16le instead
const buffer = Buffer.from('Hello', 'utf16le');
// Also valid - ucs2 is an alias for utf16le
const buffer = Buffer.from('Hello', 'ucs2');UTF-16LE is the most commonly used UTF-16 variant and works for most use cases. If you specifically need Big Endian (utf16be), you'll need a third-party library.
Node.js natively supports only these encodings:
// Supported encodings in Node.js:
'utf8' // UTF-8 (default, recommended for most text)
'utf16le' // UTF-16 Little Endian
'ucs2' // Alias for utf16le
'ascii' // 7-bit ASCII
'latin1' // ISO-8859-1 / Latin-1
'binary' // Alias for latin1
'base64' // Base64 encoding
'hex' // Hexadecimal encodingCheck your code for any encoding parameters and ensure they match one of these exact strings (lowercase is standard):
// Examples of correct usage
fs.readFileSync('file.txt', 'utf8');
buffer.toString('base64');
stream.setEncoding('utf8');If you need to work with encodings not natively supported by Node.js (like utf-16be, shift-jis, gb2312, windows-1252), install the iconv-lite package:
npm install iconv-liteThen use it to convert between encodings:
const iconv = require('iconv-lite');
// Encode to UTF-16 Big Endian
const encoded = iconv.encode('Hello World', 'utf16-be');
// Decode from Shift-JIS
const decoded = iconv.decode(buffer, 'shift-jis');
// Convert file encoding
const fs = require('fs');
const fileBuffer = fs.readFileSync('file.txt');
const text = iconv.decode(fileBuffer, 'windows-1252');iconv-lite supports over 100 encodings and is widely used in production applications, including Express.js.
Check for common typos in encoding names:
// Common mistakes:
'UTF-8' // Should be: 'utf8' (no dash, lowercase)
'UTF8' // Should be: 'utf8' (lowercase)
'utf-16' // Should be: 'utf16le'
'Unicode' // Should be: 'utf8' or 'utf16le'
'ASCII' // Should be: 'ascii' (lowercase)
// Correct usage:
fs.readFileSync('file.txt', 'utf8');
buffer.toString('ascii');While Node.js is often case-insensitive for well-known encodings, it's best practice to use lowercase to avoid issues.
When reading files with specific encodings, detect or specify the correct encoding:
const fs = require('fs');
const iconv = require('iconv-lite');
// For files with known non-UTF-8 encoding
const fileBuffer = fs.readFileSync('data.txt');
const text = iconv.decode(fileBuffer, 'windows-1252');
// For writing with specific encoding
const content = 'Hello World';
const encoded = iconv.encode(content, 'utf16-le');
fs.writeFileSync('output.txt', encoded);If the file encoding is unknown, consider using a library like chardet to detect it automatically.
UTF-16 variants: Node.js only supports UTF-16LE natively because it's the most common variant used by Windows and JavaScript's internal string representation. If you need UTF-16BE (Big Endian) or UTF-16 with BOM (Byte Order Mark), you must use iconv-lite or another encoding library.
Performance considerations: Native Node.js encodings (utf8, ascii, utf16le) are implemented in C++ and are significantly faster than third-party JavaScript implementations. Use native encodings whenever possible for performance-critical applications.
Buffer vs String encoding: When using Buffer.from(string, encoding), the encoding parameter specifies how to interpret the string. When using buffer.toString(encoding), it specifies how to decode the buffer. These are inverse operations.
Stream encoding: When setting encoding on readable streams with stream.setEncoding(encoding), only the six core encodings are supported. For other encodings, pipe the stream through iconv-lite's decodeStream().
International text: UTF-8 is the recommended encoding for international text and is the default in Node.js. It's compatible with ASCII and uses 1-4 bytes per character, making it efficient for most languages. Only use other encodings when required by external systems or legacy file formats.
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