ory/hydra · error

invalid elliptic curve key size, this algorithm does not sup

Error message

invalid elliptic curve key size, this algorithm does not support arbitrary size

What it means

josex.NewSigningKey validates the `bits` parameter before generating an EC or Ed25519 signing key. Elliptic-curve algorithms (ES256/ES384/ES512/EdDSA) map to fixed curve sizes (256, 384, 521, 256 respectively — note ES512 uses P-521, not 512), so a non-zero bits value that does not exactly equal the required size for the given algorithm is rejected with this error. The library enforces this because ECDSA and Ed25519 keys cannot be generated at arbitrary bit lengths.

Source

Thrown at oryx/josex/generate.go:43

	"crypto/rsa"
	"errors"
	"fmt"

	"github.com/go-jose/go-jose/v3"
)

// NewSigningKey generates a keypair for corresponding SignatureAlgorithm.
func NewSigningKey(alg jose.SignatureAlgorithm, bits int) (crypto.PublicKey, crypto.PrivateKey, error) {
	switch alg {
	case jose.ES256, jose.ES384, jose.ES512, jose.EdDSA:
		keylen := map[jose.SignatureAlgorithm]int{
			jose.ES256: 256,
			jose.ES384: 384,
			jose.ES512: 521, // sic!
			jose.EdDSA: 256,
		}
		if bits != 0 && bits != keylen[alg] {
			return nil, nil, errors.New("invalid elliptic curve key size, this algorithm does not support arbitrary size")
		}
	case jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512:
		if bits == 0 {
			bits = 2048
		}
		if bits < 2048 {
			return nil, nil, errors.New("invalid key size for RSA key, 2048 or more is required")
		}
	}
	switch alg {
	case jose.ES256:
		key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
		if err != nil {
			return nil, nil, err
		}
		return key.Public(), key, err
	case jose.ES384:
		key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Set bits to the exact value required by the algorithm: 256 for ES256/EdDSA, 384 for ES384, 521 (not 512) for ES512
  2. Pass bits = 0 to let the library use the correct default size for the algorithm
  3. If the algorithm is RSA (RS256/RS384/RS512/PS256/PS384/PS512), this error does not apply — verify you are not accidentally routing an EC algorithm into an RSA-sized bits value
  4. Derive bits programmatically from the algorithm (switch on alg) instead of hardcoding one size for all algorithms

Example fix

// before
key, _, err := josex.NewSigningKey(jose.ES512, 512)
// after
key, _, err := josex.NewSigningKey(jose.ES512, 521) // P-521, not 512
// or simply omit the size:
key, _, err := josex.NewSigningKey(jose.ES512, 0)
Defensive patterns

Strategy: validation

Validate before calling

func validBitsForSigning(alg jose.SignatureAlgorithm, bits int) error {
	keylen := map[jose.SignatureAlgorithm]int{
		jose.ES256: 256, jose.ES384: 384, jose.ES512: 521, jose.EdDSA: 256,
	}
	switch alg {
	case jose.ES256, jose.ES384, jose.ES512, jose.EdDSA:
		if bits != 0 && bits != keylen[alg] {
			return fmt.Errorf("%s requires bits=%d (got %d)", alg, keylen[alg], bits)
		}
	case jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512:
		if bits < 2048 {
			return fmt.Errorf("RSA requires bits>=2048 (got %d)", bits)
		}
	}
	return nil
}

Try / catch

pub, priv, err := josex.NewSigningKey(alg, bits)
if err != nil {
	if err.Error() == "invalid elliptic curve key size, this algorithm does not support arbitrary size" {
		bits = 0 // fall back to algorithm default
		pub, priv, err = josex.NewSigningKey(alg, bits)
	}
	if err != nil {
		return fmt.Errorf("generating signing key: %w", err)
	}
}

Prevention

When it happens

Trigger: Calling josex.NewSigningKey(alg, bits) with a non-zero bits that mismatches the alg: e.g. NewSigningKey(jose.ES256, 512), NewSigningKey(jose.ES512, 512) (the classic off-by-one — ES512 requires 521), NewSigningKey(jose.ES384, 256), or NewSigningKey(jose.EdDSA, 521). bits == 0 is allowed (means 'default for algorithm').

Common situations: Developers assuming ES512 maps to a 512-bit key and passing 512 (it needs 521 because P-521 is the curve); reusing a single 'keySize' config value across RSA and EC algorithms; porting code that picked a generic security level like 384 for ES256; wiring the bits flag from CLI/config without validating per-algorithm constraints.

Related errors


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/b15fae2a55a05555. Report an issue: GitHub.