denoland/deno · error · Error

ERR_CRYPTO_UNKNOWN_DH_GROUP

ERR_CRYPTO_UNKNOWN_DH_GROUP

Error message

Unknown DH group

What it means

When generateKeyPair('dh', { group }) is used, the polyfill only accepts the predefined MODP groups 'modp5', 'modp14', 'modp15', 'modp16', 'modp17', 'modp18'. Any other string reaches the allowlist check and throws ERR_CRYPTO_UNKNOWN_DH_GROUP ('Unknown DH group').

Source

Thrown at ext/node/polyfills/internal/crypto/keygen.ts:583

      const { group, primeLength, prime, generator } = options;
      if (group != null) {
        if (prime != null) {
          throw new ERR_INCOMPATIBLE_OPTION_PAIR("group", "prime");
        }
        if (primeLength != null) {
          throw new ERR_INCOMPATIBLE_OPTION_PAIR("group", "primeLength");
        }
        if (generator != null) {
          throw new ERR_INCOMPATIBLE_OPTION_PAIR("group", "generator");
        }

        validateString(group, "options.group");

        if (
          group !== "modp5" && group !== "modp14" && group !== "modp15" &&
          group !== "modp16" && group !== "modp17" && group !== "modp18"
        ) {
          throw new ERR_CRYPTO_UNKNOWN_DH_GROUP();
        }

        if (mode === kSync) {
          return op_node_generate_dh_group_key(group);
        } else {
          return op_node_generate_dh_group_key_async(group);
        }
      }

      if (prime != null) {
        if (primeLength != null) {
          throw new ERR_INCOMPATIBLE_OPTION_PAIR("prime", "primeLength");
        }

        validateBuffer(prime, "options.prime");
      } else if (primeLength != null) {
        validateInt32(primeLength, "options.primeLength", 0);
      } else {

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Map the desired bit size to a supported name: 1536→modp5, 2048→modp14, 3072→modp15, 4096→modp16, 6144→modp17, 8192→modp18
  2. For unsupported sizes, generate custom parameters (openssl dhparam) and pass options.prime instead of group
  3. Validate the group string against the allowlist before calling generateKeyPair

Example fix

// before
crypto.generateKeyPair('dh', { group: 'modp2048' });
// after
crypto.generateKeyPair('dh', { group: 'modp14' }); // 2048-bit MODP group
Defensive patterns

Strategy: validation

Validate before calling

const DH_GROUPS = ['modp5', 'modp14', 'modp15', 'modp16', 'modp17', 'modp18'];
if (!DH_GROUPS.includes(dhOptions.group)) {
  throw new Error(`Unknown DH group '${dhOptions.group}'; supported: ${DH_GROUPS.join(', ')}`);
}
crypto.generateKeyPairSync('dh', dhOptions);

Type guard

function isSupportedDhGroup(name) {
  return ['modp5', 'modp14', 'modp15', 'modp16', 'modp17', 'modp18'].includes(name);
}

Try / catch

try {
  crypto.generateKeyPairSync('dh', opts);
} catch (e) {
  if (e.code === 'ERR_CRYPTO_UNKNOWN_DH_GROUP') throw new Error(`Fix DH group name: ${opts.group}`);
  throw e;
}

Prevention

When it happens

Trigger: crypto.generateKeyPair('dh', { group: 'modp2048' }) — group values like 'modp1', 'modp2', 'modp1024', 'modp2048', custom names, or typos that are not in the modp5/modp14-18 list.

Common situations: Using IKE/RFC naming where the 2048-bit group is 'modp2048' but node:crypto calls it 'modp14'; assuming all Oakley groups are supported; copying DH group identifiers from Java JCE or OpenSSL config.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/864a16ef1cfc5db2. Report an issue: GitHub.