denoland/deno · error · DOMException
HmacImportParams.length cannot be 0
Error message
HmacImportParams.length cannot be 0
What it means
Thrown by SecretKeyObject.toCryptoKey() when the algorithm object for 'HMAC' carries length === 0. HmacImportParams.length is the HMAC key length in bits; zero is not a usable key length. The check only fires when the property is explicitly present (undefined is allowed and uses the default derived from the hash), so this almost always means code passed a computed value that evaluated to 0.
Source
Thrown at ext/node/polyfills/internal/crypto/keys.ts:806
(u: string) =>
!ArrayPrototypeIncludes(["deriveKey", "deriveBits"], u),
)
) {
throw new DOMException(
"Unsupported key usage for an HKDF key",
"SyntaxError",
);
}
} else if (algName === "HMAC") {
if (usages.length === 0) {
throw new DOMException(
"Usages cannot be empty when importing a secret key.",
"SyntaxError",
);
}
const alg = algorithm as { length?: number };
if (alg.length !== undefined && alg.length === 0) {
throw new DOMException(
"HmacImportParams.length cannot be 0",
"DataError",
);
}
} else if (algName === "KMAC128" || algName === "KMAC256") {
if (usages.length === 0) {
throw new DOMException(
"Usages cannot be empty when importing a secret key.",
"SyntaxError",
);
}
const alg = algorithm as { length?: number };
if (alg.length !== undefined && alg.length === 0) {
throw new DOMException(
"KmacImportParams.length cannot be 0",
"DataError",
);
}View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Omit length entirely to use the hash's default key length
- Pass the intended length in bits, e.g. 256
- Only include length when it is a positive number: build params conditionally
Example fix
// before
const params = { name: 'HMAC', hash: 'SHA-256', length: bits };
// after
const params = { name: 'HMAC', hash: 'SHA-256' };
if (bits > 0) params.length = bits; Defensive patterns
Strategy: validation
Validate before calling
const params: HmacImportParams = { name: 'HMAC', hash };
if (Number.isFinite(length) && length! > 0) params.length = length;
const key = secretKeyObject.toCryptoKey(params, false, usages); Type guard
const isValidHmacLength = (n: unknown): n is number => typeof n === 'number' && Number.isInteger(n) && n > 0;
Try / catch
try {
key = secretKeyObject.toCryptoKey(params, false, usages);
} catch (e) {
if (e instanceof DOMException && e.name === 'DataError' && /length cannot be 0/.test(e.message)) {
const { length: _drop, ...rest } = params;
key = secretKeyObject.toCryptoKey(rest, false, usages);
} else throw e;
} Prevention
- Treat length as optional bits, never a defaulted numeric field
- Only copy length into params when it came from a validated source
- Know that omitting length selects the hash default, which is usually what you want
When it happens
Trigger: createSecretKey(secret).toCryptoKey({ name: 'HMAC', hash: 'SHA-256', length: 0 }, false, ['sign']).
Common situations: length computed from an empty buffer's byteLength (or a *8 bit conversion of zero); config schemas that initialize numeric fields to 0; confusion between bytes and bits when filling the field programmatically.
Related errors
- Usages cannot be empty when importing a secret key.
- KmacImportParams.length cannot be 0
- ERR_CRYPTO_INVALID_KEYLEN
- Zero-length key is not supported
- PBKDF2 keys are not extractable
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/f818d6b4fdf9c6e3.
Report an issue: GitHub.