grafana/k6 · error
failed to parse elliptic curve: %w
Error message
failed to parse elliptic curve: %w
What it means
importECDSAJWK maps the JWK's crv field to a Go elliptic.Curve via pickEllipticCurve, which accepts only the canonical names 'P-256', 'P-384' and 'P-521' (case-sensitive). This error means the crv string did not match any of them; the wrapped message includes the offending value ('invalid elliptic curve <crv>'). It surfaces from crypto.subtle.importKey('jwk', ...) for ECDSA.
Source
Thrown at internal/js/modules/k6/webcrypto/jwk.go:233
exported.Set("d", encodeCurveBigInt(d, curveBits))
}
return exported, nil
}
func importECDSAJWK(_ EllipticCurveKind, jsonKeyData []byte) (any, CryptoKeyType, error) {
var jwkKey ecJWK
if err := json.Unmarshal(jsonKeyData, &jwkKey); err != nil {
return nil, UnknownCryptoKeyType, fmt.Errorf("failed to parse input as EC JWK key: %w", err)
}
if err := jwkKey.validate(); err != nil {
return nil, UnknownCryptoKeyType, fmt.Errorf("invalid EC JWK key: %w", err)
}
crv, err := pickEllipticCurve(jwkKey.Crv)
if err != nil {
return nil, UnknownCryptoKeyType, fmt.Errorf("failed to parse elliptic curve: %w", err)
}
x, err := base64URLDecode(jwkKey.X)
if err != nil {
return nil, UnknownCryptoKeyType, fmt.Errorf("failed to decode X coordinate: %w", err)
}
y, err := base64URLDecode(jwkKey.Y)
if err != nil {
return nil, UnknownCryptoKeyType, fmt.Errorf("failed to decode Y coordinate: %w", err)
}
pk := &ecdsa.PublicKey{
Curve: crv,
X: new(big.Int).SetBytes(x),
Y: new(big.Int).SetBytes(y),
}
View on GitHub (pinned to 93accf6570)
Solutions
- Use exactly 'P-256', 'P-384' or 'P-521' in the crv field
- Map alternate names before import: secp256r1/prime256v1 -> P-256, secp384r1 -> P-384, secp521r1 -> P-521
- For unsupported curves (P-224, secp256k1), switch to a supported curve or export/recreate the key
- Keep namedCurve in the algorithm object consistent with the JWK's crv
Example fix
// before
const jwk = { kty: 'EC', crv: 'secp256r1', x, y };
// after
const jwk = { kty: 'EC', crv: 'P-256', x, y }; Defensive patterns
Strategy: validation
Validate before calling
const CANON = { 'P-256':1, 'P-384':1, 'P-521':1 };
const ALIAS = { secp256r1:'P-256', prime256v1:'P-256', secp384r1:'P-384', secp521r1:'P-521' };
function normalizeCrv(crv) { return CANON[crv] ? crv : ALIAS[crv]; }
const crv = normalizeCrv(jwk.crv);
if (!crv) throw new Error('unsupported crv: ' + jwk.crv); Type guard
function isSupportedCrv(crv) {
return crv === 'P-256' || crv === 'P-384' || crv === 'P-521';
} Try / catch
try {
key = await crypto.subtle.importKey('jwk', jwk, alg, true, usages);
} catch (e) {
if (e.message.includes('failed to parse elliptic curve')) {
throw new Error(`crv "${jwk.crv}" unsupported; use P-256/P-384/P-521`);
}
throw e;
} Prevention
- Canonicalize curve names at the boundary where keys enter your system
- Keep algorithm namedCurve and JWK crv in sync
- Remember P-224, secp256k1 and Ed25519 are not supported by this importer
When it happens
Trigger: A crv of 'p-256' (lowercase), 'P256', 'prime256v1', 'secp256r1', 'P-224', 'Ed25519', or any non-canonical spelling; also a crv copied from a different curve family.
Common situations: JWKs converted from OpenSSL/JOSE libraries that emit SEC or ASN.1 curve names; hand-built JWKs; casing drift between systems; attempts to import curves k6 does not support (P-224, secp256k1, Ed25519).
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse input as EC JWK key: %w
- invalid EC JWK key: %w
- failed to decode X coordinate: %w
- failed to decode Y coordinate: %w
- failed to decode D: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/ef3c844da4ab4468.
Report an issue: GitHub.