ory/hydra · error

invalid key size for RSA key, 2048 or more is required

Error message

invalid key size for RSA key, 2048 or more is required

What it means

josex.NewSigningKey enforces a minimum RSA modulus of 2048 bits for the RS256/RS384/RS512 and PS256/PS384/PS512 signature algorithms. If bits is non-zero and less than 2048, key generation is refused because shorter RSA keys are considered insecure. bits == 0 defaults to 2048.

Source

Thrown at oryx/josex/generate.go:50

// 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)
		if err != nil {
			return nil, nil, err
		}
		return key.Public(), key, err
	case jose.ES512:
		key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
		if err != nil {

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Pass bits >= 2048 (2048 is the common default; 3072/4096 for longer-term keys)
  2. Pass bits = 0 to accept the library default of 2048
  3. Update legacy configuration that still specifies 1024-bit RSA
  4. If you intended an elliptic-curve key, switch the algorithm to ES256/ES384/ES512 or EdDSA, where sizes are 256/384/521

Example fix

// before
key, _, err := josex.NewSigningKey(jose.RS256, 1024)
// after
key, _, err := josex.NewSigningKey(jose.RS256, 2048)
// or rely on the default:
key, _, err := josex.NewSigningKey(jose.RS256, 0)
Defensive patterns

Strategy: validation

Validate before calling

func validBitsForSigning(alg jose.SignatureAlgorithm, bits int) error {
	switch alg {
	case jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512:
		if bits != 0 && bits < 2048 {
			return fmt.Errorf("%s requires bits>=2048 (got %d)", alg, bits)
		}
	}
	return nil
}

Try / catch

pub, priv, err := josex.NewSigningKey(jose.RS256, bits)
if err != nil {
	if strings.Contains(err.Error(), "2048 or more is required") {
		bits = 2048
		pub, priv, err = josex.NewSigningKey(jose.RS256, bits)
	}
	if err != nil {
		return fmt.Errorf("generating RSA signing key: %w", err)
	}
}

Prevention

When it happens

Trigger: Calling josex.NewSigningKey(jose.RS256, 1024), NewSigningKey(jose.PS256, 512), or any RSA-family signature algorithm with 0 < bits < 2048.

Common situations: Legacy configs specifying 1024-bit RSA keys from older security policies; copying example code that used 1024 or 1536; a shared 'keyBits' setting meant for EC (256/384) being applied to RSA algorithms; environment-driven key-size configuration not validated on startup.

Related errors


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