ory/hydra · error
invalid elliptic curve key size, use one of 256, 384, or 521
Error message
invalid elliptic curve key size, use one of 256, 384, or 521
What it means
josex.NewEncryptionKey generates ECDH keys for the ECDH_ES / ECDH_ES_A*KW key algorithms on one of three NIST curves selected by the bits parameter: 256 (P-256, also the default when bits == 0), 384 (P-384), or 521 (P-521). Any other non-zero value falls through to this error because elliptic curves cannot be generated at arbitrary sizes.
Source
Thrown at oryx/josex/generate.go:111
if bits < 2048 {
return nil, nil, errors.New("invalid key size for RSA key, 2048 or more is required")
}
key, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, nil, err
}
return key.Public(), key, err
case jose.ECDH_ES, jose.ECDH_ES_A128KW, jose.ECDH_ES_A192KW, jose.ECDH_ES_A256KW:
var crv elliptic.Curve
switch bits {
case 0, 256:
crv = elliptic.P256()
case 384:
crv = elliptic.P384()
case 521:
crv = elliptic.P521()
default:
return nil, nil, errors.New("invalid elliptic curve key size, use one of 256, 384, or 521")
}
key, err := ecdsa.GenerateKey(crv, rand.Reader)
if err != nil {
return nil, nil, err
}
return key.Public(), key, err
default:
return nil, nil, fmt.Errorf("unknown algorithm %s for encryption key", alg)
}
}
View on GitHub (pinned to 4174065ffb)
Solutions
- Use bits = 256, 384, or 521 for ECDH_ES* algorithms (256 is the default; note 521, not 512)
- Pass bits = 0 to get the default P-256 key
- Do not derive bits from the AES key-wrap name (A128KW still uses a P-256/P-384/P-521 curve, not 128)
- Map your security-level setting to the nearest supported curve size before calling
Example fix
// before pub, priv, err := josex.NewEncryptionKey(jose.ECDH_ES, 512) // after pub, priv, err := josex.NewEncryptionKey(jose.ECDH_ES, 521) // P-521 // or default P-256: pub, priv, err := josex.NewEncryptionKey(jose.ECDH_ES, 0)
Defensive patterns
Strategy: validation
Validate before calling
func validBitsForECDH(bits int) error {
switch bits {
case 0, 256, 384, 521:
return nil
default:
return fmt.Errorf("ECDH key size must be 0 (default P-256), 256, 384, or 521 (got %d)", bits)
}
} Try / catch
pub, priv, err := josex.NewEncryptionKey(jose.ECDH_ES, bits)
if err != nil {
if strings.Contains(err.Error(), "use one of 256, 384, or 521") {
bits = 0 // default P-256
pub, priv, err = josex.NewEncryptionKey(jose.ECDH_ES, bits)
}
if err != nil {
return fmt.Errorf("generating ECDH encryption key: %w", err)
}
} Prevention
- Use only 256, 384, 521 (or 0) for ECDH_ES* key generation — 512 is not valid even though ES512 exists (it means P-521)
- Do not derive the curve size from the AES key-wrap name (A128KW ≠ 128-bit curve)
- Pass bits=0 to accept the default P-256
- Centralize key-size selection in one helper that maps algorithms to allowed sizes
When it happens
Trigger: Calling josex.NewEncryptionKey(jose.ECDH_ES, 512) (expecting 512 like ES512), NewEncryptionKey(jose.ECDH_ES_A128KW, 128), NewEncryptionKey(jose.ECDH_ES_A256KW, 528), or any ECDH_* algorithm with bits not in {0, 256, 384, 521}.
Common situations: Assuming the AES key-wrap size (A128KW/A192KW/A256KW: 128/192/256) is the curve size and passing 128 or 192; confusing ES512's 512 with the required 521; a generic 'security level' config (e.g. 192) fed into every key-generation call.
Related errors
- invalid elliptic curve key size, this algorithm does not sup
- invalid key size for RSA key, 2048 or more is required
- unknown algorithm %s for signing key
- unknown algorithm %s for encryption key
- cookiex: at least one secret is required
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/7b298c4c0379219e.
Report an issue: GitHub.