denoland/deno · error · TypeError

ERR_INCOMPATIBLE_OPTION_PAIR

ERR_INCOMPATIBLE_OPTION_PAIR

Error message

Option "group" cannot be used in combination with option "prime"

What it means

DH key generation via generateKeyPair('dh', options) takes parameters from either a predefined MODP group (options.group) or custom parameters (options.prime / options.primeLength). These sources are mutually exclusive; supplying group together with prime throws ERR_INCOMPATIBLE_OPTION_PAIR before any key is generated.

Source

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

    }
    case "ed448": {
      if (mode === kSync) {
        return op_node_generate_ed448_key();
      }
      return op_node_generate_ed448_key_async();
    }
    case "x448": {
      if (mode === kSync) {
        return op_node_generate_x448_key();
      }
      return op_node_generate_x448_key_async();
    }
    case "dh": {
      validateObject(options, "options");
      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) {

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Use group alone for predefined RFC 3526 groups: { group: 'modp14' }
  2. Or use custom parameters without group: { prime: <Buffer> } or { primeLength: 2048 }
  3. Strip the conflicting key before calling generateKeyPair when options come from merged sources

Example fix

// before
crypto.generateKeyPair('dh', { group: 'modp14', prime: primeBuffer });
// after
crypto.generateKeyPair('dh', { group: 'modp14' });
Defensive patterns

Strategy: validation

Validate before calling

const { group, prime, primeLength } = dhOptions;
if (group != null && (prime != null || primeLength != null)) {
  throw new Error('DH group cannot be combined with prime/primeLength');
}
crypto.generateKeyPairSync('dh', dhOptions);

Type guard

function isCleanDhOptions(o) {
  const group = o.group != null, prime = o.prime != null, len = o.primeLength != null;
  return group ? !(prime || len || o.generator != null) : true;
}

Try / catch

try {
  crypto.generateKeyPairSync('dh', opts);
} catch (e) {
  if (e.code === 'ERR_INCOMPATIBLE_OPTION_PAIR') {
    if (opts.group != null) delete opts.prime; // pick group as the winner
    return crypto.generateKeyPairSync('dh', opts);
  }
  throw e;
}

Prevention

When it happens

Trigger: crypto.generateKeyPair('dh', { group: 'modp14', prime: primeBuffer }) — any dh options object where group and prime are both non-null.

Common situations: Config templates that set every DH option 'to be safe'; merging a default group with user-supplied custom primes; porting code that assembles the options object dynamically without clearing conflicting keys.

Related errors


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