ory/hydra · error

jwksx: key size must be at least 2038448 bit for algorithm "

Error message

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

What it means

generate() requires HS384 HMAC keys to be at least 384 bits. The error message contains a typo — it says "2038448 bit" — but the actual check is bits < 384, so this error fires for any HS384 request below 384 bits. bits=0 defaults to 384.

Source

Thrown at oryx/jwksx/generator.go:86

		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
		}
		if bits < 512 {
			return nil, errors.Errorf(`jwksx: key size must be at least 512 bit for algorithm "%s"`, alg)
		}
	}

	switch alg {
	case jose.ES256:
		// The cryptographic operations are implemented using constant-time algorithms.
		key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
		return key, errors.Wrapf(err, "jwks: unable to generate key")
	case jose.ES384:
		// NB: The cryptographic operations do not use constant-time algorithms.
		key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Pass bits >= 384 for HS384 (or bits=0 to use the 384 default)
  2. If 256 bits is desired, switch the algorithm to HS256
  3. Also note the key must later be a multiple of 8 bits or a second error is returned

Example fix

// before
jwks, err := jwksx.GenerateSigningKeys("kid", "HS384", 256)
// after
jwks, err := jwksx.GenerateSigningKeys("kid", "HS384", 384) // 0 also works
Defensive patterns

Strategy: validation

Validate before calling

if alg == "HS384" && bits != 0 && bits < 384 {
	return fmt.Errorf("HS384 needs >= 384 bits, got %d", bits)
}

Try / catch

jwks, err := jwksx.GenerateSigningKeys(id, "HS384", bits)
if err != nil && strings.Contains(err.Error(), "HS384") || strings.Contains(err.Error(), "2038448") {
	return fmt.Errorf("HS384 key size must be >= 384 bits, got %d", bits)
}

Prevention

When it happens

Trigger: Calling GenerateSigningKeys(id, "HS384", bits) with a non-zero bits value less than 384, e.g. 256 or 128. Note HS256 is legitimate at 256 bits, but HS384 is not.

Common situations: Reusing an HS256-sized (256-bit) key config for HS384; typos in config; assuming all HS* algorithms share the same minimum size; confusion caused by the garbled "2038448" message when debugging.

Related errors


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