grafana/k6 · error

curve not supported for converting to ECDSA key

Error message

curve not supported for converting to ECDSA key

What it means

When an ECDH key is exported to JWK, k6 must internally represent it as an ECDSA-style key to fill the x/y/crv fields (exportECJWK in webcrypto/jwk.go:196). convertPublicECDHtoECDSA (internal/js/modules/k6/webcrypto/elliptic_curve.go:696) only maps the three NIST curves (P-256/P-384/P-521) from ecdh to elliptic; an ECDH key on any other curve (e.g. X25519) returns "curve not supported for converting to ECDSA key", wrapped as "failed to convert ECDH key to ECDSA key: ...".

Source

Thrown at internal/js/modules/k6/webcrypto/elliptic_curve.go:706

	}

	return &ecdsa.PrivateKey{
		PublicKey: *pk,
		D:         new(big.Int).SetBytes(k.Bytes()),
	}, nil
}

func convertPublicECDHtoECDSA(k *ecdh.PublicKey) (*ecdsa.PublicKey, error) {
	var crv elliptic.Curve
	switch k.Curve() {
	case ecdh.P256():
		crv = elliptic.P256()
	case ecdh.P384():
		crv = elliptic.P384()
	case ecdh.P521():
		crv = elliptic.P521()
	default:
		return nil, errors.New("curve not supported for converting to ECDSA key")
	}

	x, y := elliptic.Unmarshal(crv, k.Bytes()) //nolint:staticcheck // we need to use the Unmarshal function
	if x == nil {
		return nil, fmt.Errorf("unable to convert ECDH public key to ECDSA public key, curve: %s", crv.Params().Name)
	}

	return &ecdsa.PublicKey{
		Curve: crv,
		X:     x,
		Y:     y,
	}, nil
}

func ensureKeysUseSameCurve(k1, k2 CryptoKey) error {
	ecAlg1, ok1 := k1.Algorithm.(EcKeyAlgorithm)
	ecAlg2, ok2 := k2.Algorithm.(EcKeyAlgorithm)
	if !ok1 || !ok2 {

View on GitHub (pinned to 93accf6570)

Solutions

  1. Generate ECDH keys with namedCurve 'P-256'/'P-384'/'P-521' in k6
  2. Re-import the key inside k6 from its raw/JWK form so it goes through k6's own validation
  3. If it persists on stock k6, file an issue with the script and key (public parts only)
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED_ECDH_CURVES = ['P-256', 'P-384', 'P-521'];
if (key.algorithm.name === 'ECDH' && !SUPPORTED_ECDH_CURVES.includes(key.algorithm.namedCurve)) {
  throw new Error('cannot JWK-export an ECDH key on a non-NIST curve');
}

Type guard

const isSupportedCurve = (c) => ['P-256', 'P-384', 'P-521'].includes(c);

Try / catch

try {
  jwk = await crypto.subtle.exportKey('jwk', ecdhKey);
} catch (e) {
  if (String(e.message).includes('curve not supported')) throw new Error('regenerate the ECDH key on P-256/P-384/P-521 before JWK export');
  throw e;
}

Prevention

When it happens

Trigger: `crypto.subtle.exportKey('jwk', ecdhKey)` where the ECDH key uses a non-NIST curve such as X25519. Because k6's own generate/import paths only create NIST-curve ECDH keys (pickECDHCurve rejects others), this is primarily a defensive branch.

Common situations: Practically limited to custom builds, imported keys with unusual internal state, or future curve support gaps; stock k6 rejects non-NIST ECDH curves earlier with "invalid ECDH curve".

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/27616017a236d0f4. Report an issue: GitHub.