OpenNHP/opennhp · error

cookie signing key must be exactly 32 bytes after base64…

Error message

cookie signing key must be exactly 32 bytes after base64 decode, got %d

What it means

Raised by decodeCookieSigningKey after a successful base64 decode: the decoded cookie signing key is not exactly 32 bytes. Cookie signing (HMAC-style) requires a 32-byte key, so a key of any other length — including a truncated or double-pasted one — is rejected. An empty input is allowed and falls back to a random per-process key; this error is specifically for wrong-length non-empty keys.

Solutions

  1. Generate exactly 32 bytes of entropy and base64-encode it (openssl rand -base64 32)
  2. Verify no characters were dropped or duplicated when pasting into config
  3. If running multiple server instances that must share cookies, distribute the same corrected 32-byte key to all of them
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at endpoints/server/config.go:49 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at endpoints/server/config.go:49

// Keep this in sync with docker/nhp-server/etc/config.toml (and
// docker/nhp-server/etc2/config.toml, which intentionally shares the
// same value to enable the same-key multi-instance demo). If we ever
// rotate the demo key, update this constant in the same commit.
const shippedDemoCookieSigningKeyBase64 = "w62S2G1P5GOG66Y5tIv3WlfBv8CNBdDe2JJDFr9Q+h0="

// decodeCookieSigningKey parses a base64-encoded 32-byte cookie signing
// key. An empty input yields (nil, nil): the caller will fall back to a
// random per-process key, which is fine for single-instance deployments.
func decodeCookieSigningKey(b64 string) ([]byte, error) {
	if b64 == "" {
		return nil, nil
	}
	raw, err := base64.StdEncoding.DecodeString(b64)
	if err != nil {
		return nil, fmt.Errorf("base64 decode failed: %w", err)
	}
	if len(raw) != 32 {
		return nil, fmt.Errorf("cookie signing key must be exactly 32 bytes after base64 decode, got %d", len(raw))
	}
	return raw, nil
}

var (
	baseConfigWatch  io.Closer
	httpConfigWatch  io.Closer
	acConfigWatch    io.Closer
	agentConfigWatch io.Closer
	resConfigWatch   io.Closer
	srcipConfigWatch io.Closer
	dbConfigWatch    io.Closer
	relayConfigWatch io.Closer
	teeWatch         io.Closer
	errLoadConfig    = fmt.Errorf("config load error")
)

type ServerEtcdConfig struct {

View on GitHub (pinned to 6e04ca5ff0)