grafana/k6 · error
invalid ECDH curve
Error message
invalid ECDH curve
What it means
pickECDHCurve (internal/js/modules/k6/webcrypto/elliptic_curve.go:391) maps the namedCurve string of an ECDH operation to a Go ecdh.Curve. Only the NIST curves 'P-256', 'P-384' and 'P-521' (their canonical spellings) are supported; any other value falls through to "invalid ECDH curve". It is used when generating, importing, or deriving with ECDH keys.
Source
Thrown at internal/js/modules/k6/webcrypto/elliptic_curve.go:399
return rawPrivateKey, &rawPrivateKey.PublicKey, nil
}
// isValidEllipticCurve returns true if the given elliptic curve is supported,
func isValidEllipticCurve(curve EllipticCurveKind) bool {
return curve == EllipticCurveKindP256 || curve == EllipticCurveKindP384 || curve == EllipticCurveKindP521
}
func pickECDHCurve(k string) (ecdh.Curve, error) {
switch k {
case p256Canonical:
return ecdh.P256(), nil
case p384Canonical:
return ecdh.P384(), nil
case p521Canonical:
return ecdh.P521(), nil
default:
return nil, errors.New("invalid ECDH curve")
}
}
func pickEllipticCurve(k string) (elliptic.Curve, error) {
switch k {
case p256Canonical:
return elliptic.P256(), nil
case p384Canonical:
return elliptic.P384(), nil
case p521Canonical:
return elliptic.P521(), nil
default:
return nil, errors.New("invalid elliptic curve " + k)
}
}
func exportECKey(ck *CryptoKey, format KeyFormat) (any, error) {
if ck.handle == nil {View on GitHub (pinned to 93accf6570)
Solutions
- Use one of the supported curves: 'P-256', 'P-384', or 'P-521'
- Fix casing/spelling — the canonical form is uppercase 'P-XXX'
- If you need X25519-style curves, do the ECDH outside k6 (e.g. against a service) since webcrypto in k6 only supports NIST curves
Example fix
// before
const pair = await crypto.subtle.generateKey({ name: 'ECDH', namedCurve: 'X25519' }, true, ['deriveKey']);
// after
const pair = await crypto.subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveKey']); Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED_ECDH_CURVES = ['P-256', 'P-384', 'P-521'];
if (!SUPPORTED_ECDH_CURVES.includes(namedCurve)) {
throw new Error(`unsupported ECDH curve ${namedCurve}; use one of ${SUPPORTED_ECDH_CURVES.join(', ')}`);
} Type guard
const isSupportedCurve = (c) => ['P-256', 'P-384', 'P-521'].includes(c);
Try / catch
try {
pair = await crypto.subtle.generateKey({ name: 'ECDH', namedCurve }, true, ['deriveBits']);
} catch (e) {
if (String(e.message).includes('invalid ECDH curve')) throw new Error(`curve '${namedCurve}' not supported; use P-256/P-384/P-521`);
throw e;
} Prevention
- Define the curve once as a constant ('P-256') and reuse it everywhere
- Spell curves exactly as P-256/P-384/P-521 — matching case and dash
- Check peer systems' curve before porting ECDH code from Node/browsers
When it happens
Trigger: `crypto.subtle.generateKey({ name: 'ECDH', namedCurve: 'X25519' }, ...)` or namedCurve values like 'secp256k1', 'P-256K', 'p-256', 'Ed25519'; also importing a JWK ECDH key whose crv is not one of the three supported curves.
Common situations: Porting crypto code from Node.js/browsers that support X25519; typos or wrong case in the curve name; interoperating with systems that default to non-NIST curves.
Related errors
- invalid elliptic curve {k}
- keys are not valid elliptic curve keys
- keys have different curves {curve1} and {curve2}
- unable to convert ECDH public key to ECDSA public key, curve
- failed to convert ECDH key to ECDSA key: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/4d77c6cb2157d288.
Report an issue: GitHub.