ory/hydra · critical

panic during JSON Web Key generation for set %q: %v

Error message

panic during JSON Web Key generation for set %q: %v

What it means

This error converts a panic raised inside the singleflight-generated JWK creation into a normal error. Without the recover, a panic in singleflight.Do would crash the entire process, including concurrent requests waiting on the same flight. The message reports the JWK set name and the recovered panic value.

Source

Thrown at jwk/helper.go:90

	// The network ID scopes the flight to one tenant. The NUL separators keep
	// distinct (set, kid) tuples from mapping to the same key; results are
	// shared between all callers on the same key, so the key must never be
	// ambiguous.
	key := r.Networker().NetworkID(ctx).String() + "\x00" + set + "\x00" + kid

	// A flight is bounded by generateTimeout, so waiting much longer than that
	// means it died without delivering (e.g. runtime.Goexit in a test); error
	// out rather than blocking forever.
	ctx, cancel := context.WithTimeout(ctx, 2*generateTimeout)
	defer cancel()

	ch := generateFlight.DoChan(key, func() (_ any, err error) {
		// A panic must surface as an error: singleflight would otherwise
		// crash the whole process when channel waiters are present.
		defer func() {
			if e := recover(); e != nil {
				err = errors.Errorf("panic during JSON Web Key generation for set %q: %v", set, e)
			}
		}()

		// The flight must not be canceled by the request that happened to
		// start it: other requests may be waiting on the result. Context
		// values (network ID, tracing) are preserved.
		fctx, cancel := context.WithTimeout(context.WithoutCancel(ctx), generateTimeout)
		defer cancel()

		return readOrGenerateKeySet(fctx, r, set, kid, alg, use)
	})

	select {
	case <-ctx.Done():
		return nil, errors.WithStack(ctx.Err())
	case result := <-ch:
		if result.Err != nil {
			return nil, result.Err

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Inspect the %v payload in the log to identify the panicking code path inside the JWK generation flight
  2. Fix the root cause in the key-generation code (check crypto/rand availability, memory limits for RSA 4096, uuid generation)
  3. Retry the request — the error is transient from the caller's perspective and the flight result is not cached on panic
  4. Reduce concurrency pressure on the same JWK set while investigating
Defensive patterns

Strategy: try-catch

Try / catch

keys, err := mgr.GetOrGenerateKeySet(ctx, set)
if err != nil {
    if strings.Contains(err.Error(), "panic during JSON Web Key generation") {
        log.WithError(err).Error("jwk generation panicked; retrying")
        return retryWithBackoff(ctx, func() error { _, err := mgr.GetOrGenerateKeySet(ctx, set); return err })
    }
    return err
}

Prevention

When it happens

Trigger: Any panic thrown inside the flight function that generates keys for a JWK set — e.g. nil dereference in key generation, uuid.Must failing, crypto randomness unavailable, or a bug in josex.NewSigningKey — while other requests may be waiting on the same singleflight channel.

Common situations: Hardware/OS-level entropy failures (crypto/rand read error panics or uuid.Must panics); concurrent first-time key generation for the same set triggering a latent bug; memory exhaustion during 4096-bit RSA key generation under load.

Related errors


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