{"record":{"id":"90da19d5a6a1e16d","repo":"denoland/deno","slug":"err-ossl-dh-modulus-too-small","errorCode":"ERR_OSSL_DH_MODULUS_TOO_SMALL","errorMessage":"modulus too small","messagePattern":"modulus too small","errorType":"error_code","errorClass":"NodeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/diffiehellman.ts","lineNumber":180,"sourceCode":"      if (isArrayBufferView(sizeOrKey) || isAnyArrayBuffer(sizeOrKey)) {\n        if (isArrayBufferView(sizeOrKey)) {\n          const parts = getViewParts(sizeOrKey as ArrayBufferView);\n          this.#prime = Buffer.from(parts.ab, parts.off, parts.len);\n        } else {\n          this.#prime = Buffer.from(\n            sizeOrKey,\n            0,\n            ArrayBufferPrototypeGetByteLength(sizeOrKey as ArrayBuffer),\n          );\n        }\n      } else {\n        this.#prime = toBuf(sizeOrKey as string, keyEncoding as string);\n      }\n    } else {\n      // The supplied parameter is our primeLength, generate a suitable prime.\n      this.#primeLength = sizeOrKey as number;\n      if (this.#primeLength < 2) {\n        throw new NodeError(\n          \"ERR_OSSL_DH_MODULUS_TOO_SMALL\",\n          \"modulus too small\",\n        );\n      }\n\n      this.#prime = Buffer.from(\n        TypedArrayPrototypeGetBuffer(\n          op_node_gen_prime(this.#primeLength, false, null, null),\n        ),\n      );\n    }\n\n    if (!generator) {\n      generator = DH_GENERATOR;\n    }\n\n    if (typeof generator === \"number\") {\n      validateInt32(generator, \"generator\");","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/diffiehellman.ts#L162-L198","documentation":"When DiffieHellman is constructed with a numeric prime length instead of prime material, lengths below 2 throw ERR_OSSL_DH_MODULUS_TOO_SMALL ('modulus too small') at diffiehellman.ts:180, mirroring OpenSSL's floor for DH prime generation. Only 0 and 1 are rejected here — but such sizes are cryptographically worthless anyway.","triggerScenarios":"new DiffieHellman(0) or new DiffieHellman(1); createDiffieHellman(Number(cfg.dhBits)) where cfg.dhBits is unset/NaN/0; byte-length values (16, 32) confused with bit lengths after arithmetic errors produce small numbers.","commonSituations":"Bit-size env var missing so Number(undefined) -> NaN or a 0 default; test fixtures with toy sizes; unit mix-ups between bits and bytes in config.","solutions":["Pass a real bit length — 2048 or 3072 in production (values < 2 throw here, but anything small is insecure)","Validate the configured size (integer, >= 2048) in one place before constructing","Check bits-vs-bytes mix-ups: the constructor takes bits"],"exampleFix":"// before\nnew DiffieHellman(Number(process.env.DH_BITS ?? 0)); // 0 -> modulus too small\n\n// after\nconst bits = Number(process.env.DH_BITS ?? 2048);\nif (!Number.isInteger(bits) || bits < 2048) throw new Error('DH_BITS must be an integer >= 2048');\nnew DiffieHellman(bits);","handlingStrategy":"validation","validationCode":"function assertDhBits(n) {\n  if (!Number.isInteger(n) || n < 2) throw new RangeError('DH prime length must be an integer >= 2');\n  if (n < 2048) console.warn('DH primes below 2048 bits are insecure');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set DH size explicitly (2048/3072) instead of computing it from other values","Treat modulus size as security configuration and validate it in one place at startup"],"tags":["crypto","diffiehellman","security","validation"],"backgroundTag":"weak-dh-parameters","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}