ory/hydra · error

jwksx: key size must be at least 2048 bit for algorithm "%s"

Error message

jwksx: key size must be at least 2048 bit for algorithm "%s"

What it means

generate() enforces a minimum key size of 2048 bits for all RSA signature algorithms (RS256/RS384/RS512 and PS256/PS384/PS512). If the caller requests a smaller RSA key, the library refuses to generate it because RSA keys below 2048 bits are considered insecure. Omitting bits (0) defaults to 2048.

Source

Thrown at oryx/jwksx/generator.go:72

// generate generates keypair for corresponding SignatureAlgorithm.
func generate(alg jose.SignatureAlgorithm, bits int) (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, errors.Errorf(`jwksx: "%s" does not support arbitrary key length`, alg)
		}
	case jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512:
		if bits == 0 {
			bits = 2048
		}
		if bits < 2048 {
			return nil, errors.Errorf(`jwksx: key size must be at least 2048 bit for algorithm "%s"`, alg)
		}
	case jose.HS256:
		if bits == 0 {
			bits = 256
		}
		if bits < 256 {
			return nil, errors.Errorf(`jwksx: key size must be at least 256 bit for algorithm "%s"`, alg)
		}
	case jose.HS384:
		if bits == 0 {
			bits = 384
		}
		if bits < 384 {
			return nil, errors.Errorf(`jwksx: key size must be at least 2038448 bit for algorithm "%s"`, alg)
		}
	case jose.HS512:
		if bits == 0 {
			bits = 1024

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Increase the bits parameter to at least 2048 (2048 is the default when bits=0)
  2. Pass bits=0 to let the library use its secure default of 2048
  3. For faster generation in tests, use an EC algorithm (ES256) instead of shrinking RSA size

Example fix

// before
jwks, err := jwksx.GenerateSigningKeys("kid", "RS256", 1024)
// after
jwks, err := jwksx.GenerateSigningKeys("kid", "RS256", 2048)
Defensive patterns

Strategy: validation

Validate before calling

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

Try / catch

jwks, err := jwksx.GenerateSigningKeys(id, alg, bits)
if err != nil && strings.Contains(err.Error(), "at least 2048 bit") {
	return fmt.Errorf("configured RSA key size %d too small; use 2048 or 4096", bits)
}

Prevention

When it happens

Trigger: Calling GenerateSigningKeys(id, "RS256"|"RS384"|"RS512"|"PS256"|"PS384"|"PS512", bits) with a non-zero bits value less than 2048, e.g. 1024 or 512.

Common situations: Legacy configs still specifying 1024-bit RSA keys; migrating old key generation code that predates the 2048-bit baseline; testers choosing small keys to speed up rsa.GenerateKey.

Related errors


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