{"record":{"id":"f818d6b4fdf9c6e3","repo":"denoland/deno","slug":"hmacimportparams-length-cannot-be-0","errorCode":null,"errorMessage":"HmacImportParams.length cannot be 0","messagePattern":"HmacImportParams\\.length cannot be 0","errorType":"exception","errorClass":"DOMException","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/keys.ts","lineNumber":806,"sourceCode":"          (u: string) =>\n            !ArrayPrototypeIncludes([\"deriveKey\", \"deriveBits\"], u),\n        )\n      ) {\n        throw new DOMException(\n          \"Unsupported key usage for an HKDF key\",\n          \"SyntaxError\",\n        );\n      }\n    } else if (algName === \"HMAC\") {\n      if (usages.length === 0) {\n        throw new DOMException(\n          \"Usages cannot be empty when importing a secret key.\",\n          \"SyntaxError\",\n        );\n      }\n      const alg = algorithm as { length?: number };\n      if (alg.length !== undefined && alg.length === 0) {\n        throw new DOMException(\n          \"HmacImportParams.length cannot be 0\",\n          \"DataError\",\n        );\n      }\n    } else if (algName === \"KMAC128\" || algName === \"KMAC256\") {\n      if (usages.length === 0) {\n        throw new DOMException(\n          \"Usages cannot be empty when importing a secret key.\",\n          \"SyntaxError\",\n        );\n      }\n      const alg = algorithm as { length?: number };\n      if (alg.length !== undefined && alg.length === 0) {\n        throw new DOMException(\n          \"KmacImportParams.length cannot be 0\",\n          \"DataError\",\n        );\n      }","sourceCodeStart":788,"sourceCodeEnd":824,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/keys.ts#L788-L824","documentation":"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.","triggerScenarios":"createSecretKey(secret).toCryptoKey({ name: 'HMAC', hash: 'SHA-256', length: 0 }, false, ['sign']).","commonSituations":"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.","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"],"exampleFix":"// before\nconst params = { name: 'HMAC', hash: 'SHA-256', length: bits };\n\n// after\nconst params = { name: 'HMAC', hash: 'SHA-256' };\nif (bits > 0) params.length = bits;","handlingStrategy":"validation","validationCode":"const params: HmacImportParams = { name: 'HMAC', hash };\nif (Number.isFinite(length) && length! > 0) params.length = length;\nconst key = secretKeyObject.toCryptoKey(params, false, usages);","typeGuard":"const isValidHmacLength = (n: unknown): n is number =>\n  typeof n === 'number' && Number.isInteger(n) && n > 0;","tryCatchPattern":"try {\n  key = secretKeyObject.toCryptoKey(params, false, usages);\n} catch (e) {\n  if (e instanceof DOMException && e.name === 'DataError' && /length cannot be 0/.test(e.message)) {\n    const { length: _drop, ...rest } = params;\n    key = secretKeyObject.toCryptoKey(rest, false, usages);\n  } else throw e;\n}","preventionTips":["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"],"tags":["crypto","webcrypto","hmac","key-length","node-compat"],"backgroundTag":"webcrypto-zero-length-key","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}