OpenNHP/opennhp · error

base64 decode failed

Error message

base64 decode failed: %w

What it means

Raised by the nhp-server helper decodeCookieSigningKey: the cookie_signing_key value from config failed standard base64 decoding. This is the operator-supplied key used to sign cookies across instances; the shipped demo key constant is only a fallback reference, and a mangled copy of it (or any invalid base64) triggers this error at startup or config update.

Solutions

  1. Regenerate a 32-byte key and encode it with standard base64 (e.g. openssl rand -base64 32)
  2. Copy the full string without truncation, whitespace, or smart quotes
  3. Keep the value in sync with docker/nhp-server/etc/config.toml conventions documented in the code
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at endpoints/server/config.go:46 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/9628b2520ef15dbb. Report an issue: GitHub.

Appendix: source

Thrown at endpoints/server/config.go:46

// copy the demo and forget to rotate the key get a loud warning
// instead of silently running with a public secret.
//
// 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")

View on GitHub (pinned to 6e04ca5ff0)