ory/hydra · critical

jwks: unable to generate key

Error message

jwks: unable to generate key

What it means

This is the wrap message around a failure from crypto/ecdsa's ecdsa.GenerateKey when generating the ES256 (P-256) key. The only realistic cause is the crypto/rand entropy source failing (rand.Reader read error), which is extremely rare and usually indicates a broken system entropy pool. It can also fire even when err is nil because errors.Wrapf is called unconditionally, though wrapping a nil error returns nil in the pkg/errors used here only if it handles nil — with github.com/pkg/errors, Wrapf(nil, ...) returns nil, so this message always implies a real GenerateKey failure.

Source

Thrown at oryx/jwksx/generator.go:101

			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)
		return key, errors.Wrapf(err, "jwks: unable to generate key")
	case jose.ES512:
		// NB: The cryptographic operations do not use constant-time algorithms.
		key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
		return key, errors.Wrapf(err, "jwks: unable to generate key")
	case jose.EdDSA:
		_, key, err := ed25519.GenerateKey(rand.Reader)
		return key, errors.Wrapf(err, "jwks: unable to generate key")
	case jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512:
		key, err := rsa.GenerateKey(rand.Reader, bits)
		return key, errors.Wrapf(err, "jwks: unable to generate key")
	case jose.HS256, jose.HS384, jose.HS512:
		if bits%8 != 0 {
			return nil, errors.Errorf(`jwksx: key size must be a multiple of 8 for algorithm "%s" but got: %d`, alg, bits)
		}

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Verify the host's entropy source is functional (check /dev/urandom is readable, kernel getrandom works)
  2. Restart or fix the container/VM if its random device is broken
  3. Retry generation — entropy read failures are often transient
  4. Upgrade the Go runtime/OS if getrandom is misbehaving
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check the entropy source before generation:
if f, err := os.Open("/dev/urandom"); err != nil {
	return fmt.Errorf("entropy source unavailable: %w", err)
} else {
	f.Close()
}

Try / catch

jwks, err := jwksx.GenerateSigningKeys(id, "ES256", 0)
if err != nil && strings.Contains(err.Error(), "unable to generate key") {
	// transient entropy failure: back off and retry
	time.Sleep(100 * time.Millisecond)
	jwks, err = jwksx.GenerateSigningKeys(id, "ES256", 0)
}

Prevention

When it happens

Trigger: GenerateSigningKeys(id, "ES256", bits) passing size validation, then ecdsa.GenerateKey(elliptic.P256(), rand.Reader) returning an error — i.e. the OS entropy source (/dev/urandom, getrandom) failed.

Common situations: Running in restricted containers/VMs with a broken or exhausted entropy pool; sandboxed CI environments lacking /dev/urandom access; unusual kernels or embedded environments.

Related errors


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