denoland/deno · error · TypeError
ERR_INVALID_ARG_VALUE
ERR_INVALID_ARG_VALUE
Error message
The argument 'outputEncoding' is invalid. Received ${inspected} What it means
crypto.hash's outputEncoding (the third argument as a string, or the outputEncoding field of the options object) must name a known encoding. It is normalized like Buffer encodings; when normalizeEncoding() returns undefined only the special value 'buffer' (matched case-insensitively via toLowerCase) is rescued — every other unknown name throws ERR_INVALID_ARG_VALUE.
Source
Thrown at ext/node/polyfills/crypto.ts:173
if (typeof outputEncodingOrOptions === "object") {
outputEncoding = outputEncodingOrOptions.outputEncoding ?? "hex";
outputLength = outputEncodingOrOptions.outputLength;
} else {
outputEncoding = outputEncodingOrOptions;
}
let normalized = outputEncoding;
// Fast case: if it's 'hex', we don't need to validate it further.
if (outputEncoding !== "hex") {
validateString(outputEncoding, "outputEncoding");
normalized = normalizeEncoding(outputEncoding);
// If the encoding is invalid, normalizeEncoding() returns undefined.
if (normalized === undefined) {
// normalizeEncoding() doesn't handle 'buffer'.
if (StringPrototypeToLowerCase(outputEncoding) === "buffer") {
normalized = "buffer";
} else {
throw new ERR_INVALID_ARG_VALUE("outputEncoding", outputEncoding);
}
}
}
const algoLower = StringPrototypeToLowerCase(algorithm);
const isXof = algoLower === "shake128" || algoLower === "shake256";
if (outputLength != null && !isXof) {
// For non-XOF hashes, outputLength must match the algorithm's digest size.
const testHash = createHash(algorithm);
testHash.update("");
const expectedLen = testHash.digest().length;
if (outputLength !== expectedLen) {
throw new Error(
`Output length ${outputLength} is invalid for ${algoLower}, which does not support XOF`,
);
}
}View on GitHub (pinned to 89f33cbef2)
Solutions
- Use a supported encoding: 'hex', 'base64', 'base64url', 'utf8'/'utf-8', 'utf16le', 'latin1', 'ascii', 'binary'
- Pass 'buffer' (any case) to get a Buffer back
- Validate encoding names against an allowlist before calling
Example fix
// before
crypto.hash("sha256", "x", "base62");
// after
crypto.hash("sha256", "x", "base64url"); Defensive patterns
Strategy: validation
Validate before calling
const OK_ENCODINGS = new Set([
"hex", "base64", "base64url", "utf8", "utf-8", "utf16le",
"latin1", "ascii", "binary", "buffer",
]);
const enc = String(encoding).toLowerCase();
if (!OK_ENCODINGS.has(enc)) throw new TypeError(`unsupported encoding: ${encoding}`); Type guard
const isOutputEncoding = (e) => typeof e === "string" && OK_ENCODINGS.has(e.toLowerCase());
Try / catch
try { return crypto.hash(algo, data, enc); }
catch (e) {
if (e.code === "ERR_INVALID_ARG_VALUE" && e.message.includes("outputEncoding")) {
return crypto.hash(algo, data, "hex");
} else throw e;
} Prevention
- Restrict config-driven encoding names to the Node encoding set
- Default to 'hex' when unsure
- Trim whitespace around encoding values from config files
When it happens
Trigger: crypto.hash('sha256', 'x', 'base62'); 'hexadecimal'; 'utf8 ' with trailing space; '' (empty string). The fast path skips validation only for the exact string 'hex'; everything else goes through normalizeEncoding.
Common situations: Typos in config-driven encoding names; assuming custom encodings like 'base62' or 'ascii85' exist; casing is forgiving ('BUFFER' works) but spelling and whitespace are not.
Related errors
- ERR_INVALID_ARG_TYPE
- Output length ${outputLength} is invalid for ${algoLower}, w
- The bench name can't be empty
- If "keyFormat" is specified, it must be "pem": received "${k
- TypeError [ERR_INVALID_OPT_VALUE_ENCODING]: The value "${enc
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/0049ac74fc2b27d1.
Report an issue: GitHub.