OpenNHP/opennhp · critical

failed to generate random cookie signing key

Error message

failed to generate random cookie signing key: %v

What it means

UdpServer.Start generates a random 32-byte cookie signing key when CookieSigningKeyBase64 is unset, and returns this error if crypto/rand fails to produce those bytes. This is an environment/OS-level entropy failure, not a config problem.

Solutions

  1. Restart the process — rand.Read failures are typically transient OS-level conditions
  2. Fix the container sandbox so getrandom(2)/getentropy is permitted (adjust seccomp/AppArmor profile)
  3. Ensure /dev/urandom is available in the container or jail
  4. Set CookieSigningKeyBase64 explicitly to skip the random-generation path entirely

Example fix

// before (docker run)
docker run --security-opt seccomp:strict-random.json nhp-server
// after (allow getrandom in the profile, or pre-supply the key)
environment:
  - CookieSigningKeyBase64=<base64 32-byte key>
Defensive patterns

Strategy: try-catch

Try / catch

if err := srv.Start(); err != nil {
    if strings.Contains(err.Error(), "random cookie signing key") {
        log.Fatalf("entropy unavailable on host: %v — fix OS randomness source or set CookieSigningKeyBase64", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Start with an empty CookieSigningKeyBase64 while rand.Read on the 32-byte buffer returns an error (e.g. exhausted or blocked system entropy source).

Common situations: Containers/seccomp profiles blocking getrandom(2); misconfigured chroots lacking /dev/urandom; heavily degraded kernels in embedded environments.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/e0a705c76513fb8f. Report an issue: GitHub.

Appendix: source

Thrown at endpoints/server/udpserver.go:298

	// verify a cookie that a sibling minted. When the operator hasn't
	// configured one we mint a random per-process key — fine for a single
	// instance, broken for a cluster (the failure is silent: cookies
	// minted by replica A don't verify on replica B and the agent's RKN
	// stalls until timeout). Always log which mode we're in.
	cookieKey, cookieKeyErr := decodeCookieSigningKey(s.config.CookieSigningKeyBase64)
	if cookieKeyErr != nil {
		// Malformed (not empty) is an ops mistake — fail fast rather
		// than silently degrading to a per-process random key. Silent
		// fallback would let a cluster look healthy while its replicas
		// each mint cookies a sibling can't verify.
		log.Critical("invalid CookieSigningKeyBase64 in config: %v", cookieKeyErr)
		return fmt.Errorf("invalid CookieSigningKeyBase64: %w", cookieKeyErr)
	}
	if len(cookieKey) == 0 {
		cookieKey = make([]byte, 32)
		if _, readErr := rand.Read(cookieKey); readErr != nil {
			log.Critical("failed to generate random cookie signing key: %v", readErr)
			return fmt.Errorf("failed to generate random cookie signing key: %v", readErr)
		}
		log.Info("CookieSigningKeyBase64 not set; using a random per-process key (single-instance only — clusters must share an operator-supplied key)")
	} else {
		log.Info("CookieSigningKeyBase64 configured; cookies are stateless and shared across the cluster")
		// Catch operators who copy the docker-compose demo config and
		// forget to regenerate the shared key. The shipped value is
		// public (committed to docker/nhp-server/etc/config.toml so
		// `docker-compose up` works out of the box) — running it in
		// any environment a real client can reach lets anyone who has
		// browsed the repo mint cookies the server will accept.
		// Critical (not Warning) so it surfaces in default journalctl
		// filters and any oncall log-volume alarms.
		if s.config.CookieSigningKeyBase64 == shippedDemoCookieSigningKeyBase64 {
			log.Critical("CookieSigningKeyBase64 matches the docker-compose demo value committed at " +
				"docker/nhp-server/etc/config.toml — this key is PUBLIC. Regenerate before any " +
				"deployment reachable from outside the host (use `nhp-serverd keygen --curve` or " +
				"`openssl rand -base64 32`).")
		}

View on GitHub (pinned to 6e04ca5ff0)