denoland/deno · error · ERR_INVALID_ARG_VALUE
ERR_INVALID_ARG_VALUE
ERR_INVALID_ARG_VALUE
Error message
The argument 'type' must be a supported key type. Received ${type} What it means
crypto.generateKey and generateKeySync only create symmetric secret keys, so their option validator (ext/node/polyfills/internal/crypto/keygen.ts:81-95) accepts exactly type 'hmac' (integer length 8..2^31-1) or 'aes' (length one of 128/192/256). Any other type string falls into the default branch and throws ERR_INVALID_ARG_VALUE with 'must be a supported key type'.
Source
Thrown at ext/node/polyfills/internal/crypto/keygen.ts:89
op_node_get_public_key_from_pair,
} = core.ops;
function validateGenerateKey(
type: "hmac" | "aes",
options: { length: number },
) {
validateString(type, "type");
validateObject(options, "options");
const { length } = options;
switch (type) {
case "hmac":
validateInteger(length, "options.length", 8, 2 ** 31 - 1);
break;
case "aes":
validateOneOf(length, "options.length", kAesKeyLengths);
break;
default:
throw new ERR_INVALID_ARG_VALUE(
"type",
type,
"must be a supported key type",
);
}
}
function generateKeySync(
type: "hmac" | "aes",
options: {
length: number;
},
): KeyObject {
validateGenerateKey(type, options);
const { length } = options;
const len = Math.floor(length / 8);
View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Use crypto.generateKeyPair[Sync] for asymmetric keys (rsa, ec, ed25519, dh...).
- Use generateKey('hmac', { length: 256 }) or generateKey('aes', { length: 128|192|256 }) for symmetric secrets.
- Validate the type against ['hmac','aes'] before calling when it comes from config or user input.
Example fix
// before
crypto.generateKeySync('rsa', { length: 2048 }); // ERR_INVALID_ARG_VALUE: unsupported type
// after
const hmacKey = crypto.generateKeySync('hmac', { length: 256 });
const aesKey = crypto.generateKeySync('aes', { length: 256 });
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
}); Defensive patterns
Strategy: validation
Validate before calling
const SECRET_TYPES = new Set(['hmac', 'aes']);
function generateSecret(type, options) {
if (!SECRET_TYPES.has(type)) {
throw new Error(`generateKey supports ${[...SECRET_TYPES]}; use generateKeyPair for '${type}'`);
}
return crypto.generateKeySync(type, options);
} Type guard
function isSecretKeyType(t) {
return t === 'hmac' || t === 'aes';
} Try / catch
try {
key = crypto.generateKeySync(type, opts);
} catch (e) {
if (e.code === 'ERR_INVALID_ARG_VALUE' && /type/.test(e.message)) {
({ publicKey, privateKey } = crypto.generateKeyPairSync(type, pairOpts(type)));
} else throw e;
} Prevention
- Remember generateKey = symmetric secrets only (hmac/aes); generateKeyPair = asymmetric.
- Validate the type string when it comes from config or user input.
- For aes, restrict length to 128/192/256; for hmac, an integer byte length >= 8.
When it happens
Trigger: crypto.generateKeySync('rsa', { length: 2048 }); generateKeySync('ed25519', {...}); generateKeySync('aes', { length: 100 }); generateKey('hmac', { length: 4 }) throws a validateInteger error instead - the type throw is specifically for names outside {hmac, aes}.
Common situations: Assuming generateKey is a general-purpose generator and trying to make RSA/EC/Ed25519 keys with it; migrating from WebCrypto generateKey (which does handle asymmetric types) to node:crypto; JSON configs driving the 'type' field.
Related errors
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/ac3cf89f6f370bb9.
Report an issue: GitHub.