{"record":{"id":"880d832a304c9b07","repo":"denoland/deno","slug":"err-crypto-invalid-scrypt-params","errorCode":"ERR_CRYPTO_INVALID_SCRYPT_PARAMS","errorMessage":"Invalid scrypt params","messagePattern":"Invalid scrypt params","errorType":"error_code","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/scrypt.ts","lineNumber":188,"sourceCode":"      validateInteger(maxmem, \"maxmem\", 0);\n    }\n    if (N === 0) N = defaults.N;\n    if (r === 0) r = defaults.r;\n    if (p === 0) p = defaults.p;\n    if (maxmem === 0) maxmem = defaults.maxmem;\n  }\n\n  return { password, salt, keylen, N, r, p, maxmem };\n}\n\nfunction validateScryptParams(\n  N: number,\n  r: number,\n  p: number,\n  maxmem: number,\n) {\n  if (N < 2 || (N & (N - 1)) !== 0) {\n    throw new ERR_CRYPTO_INVALID_SCRYPT_PARAMS();\n  }\n\n  const NBig = BigInt(N);\n  const rBig = BigInt(r);\n  const pBig = BigInt(p);\n  const maxmemBig = BigInt(maxmem);\n  const rTimes16 = rBig * 16n;\n  if (\n    (rTimes16 <= 32n && NBig >= (1n << rTimes16)) ||\n    pBig * rBig > ((1n << 30n) - 1n) ||\n    128n * NBig * rBig >= maxmemBig\n  ) {\n    throw new ERR_CRYPTO_INVALID_SCRYPT_PARAMS(\n      \"error:1C800066:Provider routines::MEMORY_LIMIT_EXCEEDED\",\n    );\n  }\n}\n","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/scrypt.ts#L170-L206","documentation":"Thrown by validateScryptParams in Deno's node:crypto polyfill (ext/node/polyfills/internal/crypto/scrypt.ts:188) when the cost parameter N is less than 2 or not a power of two. scrypt's memory-hard loop requires N = 2^k (k >= 1); any other value (including 0, which falls back to the default first, then odd/custom values) fails with ERR_CRYPTO_INVALID_SCRYPT_PARAMS.","triggerScenarios":"crypto.scrypt(pw, salt, 64, { N: 3 }, cb), { N: 10000 }, or { N: 1 }. N must be exactly 2, 4, 8, ... 16384, 1048576, etc.","commonSituations":"Tuning memory cost with round numbers (10000 instead of 16384); N computed as a memory budget divided by 128*r producing a non-power-of-two; copying N from another KDF's iteration count (e.g. pbkdf2 rounds).","solutions":["Set N to the nearest power of two for your budget: 16384 (default), 32768, 65536, 1048576.","Compute N as 2 ** Math.floor(Math.log2(budget / (128 * r))) so it stays a power of two.","Keep the (N, r, p) triple from one vetted source rather than hand-tuning each value."],"exampleFix":"// before\ncrypto.scrypt(pw, salt, 64, { N: 10000, r: 8, p: 1 }, cb);\n\n// after\ncrypto.scrypt(pw, salt, 64, { N: 16384, r: 8, p: 1 }, cb);","handlingStrategy":"validation","validationCode":"const isPow2 = (n) => n >= 2 && (n & (n - 1)) === 0;\nif (!isPow2(opts.N)) opts.N = 2 ** Math.round(Math.log2(opts.N));","typeGuard":"const isValidScryptN = (n) => Number.isInteger(n) && n >= 2 && (n & (n - 1)) === 0;","tryCatchPattern":"try { crypto.scrypt(pw, salt, len, opts, cb); } catch (e) { if (e.code === 'ERR_CRYPTO_INVALID_SCRYPT_PARAMS') { opts.N = 1 << Math.round(Math.log2(opts.N)); crypto.scrypt(pw, salt, len, opts, cb); } else throw e; }","preventionTips":["Pick N from 2^k values: 16384, 32768, 65536, 1048576.","Do not port iteration counts from pbkdf2 into scrypt N."],"tags":["node-compat","crypto","scrypt","kdf","parameter-validation"],"backgroundTag":"scrypt-invalid-params","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}