{"record":{"id":"c82265af11f9c716","repo":"OpenNHP/opennhp","slug":"cookie-signing-key-must-be-exactly-32-bytes-after","errorCode":null,"errorMessage":"cookie signing key must be exactly 32 bytes after base64 decode, got %d","messagePattern":"cookie signing key must be exactly 32 bytes after base64 decode, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/server/config.go","lineNumber":49,"sourceCode":"// Keep this in sync with docker/nhp-server/etc/config.toml (and\n// docker/nhp-server/etc2/config.toml, which intentionally shares the\n// same value to enable the same-key multi-instance demo). If we ever\n// rotate the demo key, update this constant in the same commit.\nconst shippedDemoCookieSigningKeyBase64 = \"w62S2G1P5GOG66Y5tIv3WlfBv8CNBdDe2JJDFr9Q+h0=\"\n\n// decodeCookieSigningKey parses a base64-encoded 32-byte cookie signing\n// key. An empty input yields (nil, nil): the caller will fall back to a\n// random per-process key, which is fine for single-instance deployments.\nfunc decodeCookieSigningKey(b64 string) ([]byte, error) {\n\tif b64 == \"\" {\n\t\treturn nil, nil\n\t}\n\traw, err := base64.StdEncoding.DecodeString(b64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"base64 decode failed: %w\", err)\n\t}\n\tif len(raw) != 32 {\n\t\treturn nil, fmt.Errorf(\"cookie signing key must be exactly 32 bytes after base64 decode, got %d\", len(raw))\n\t}\n\treturn raw, nil\n}\n\nvar (\n\tbaseConfigWatch  io.Closer\n\thttpConfigWatch  io.Closer\n\tacConfigWatch    io.Closer\n\tagentConfigWatch io.Closer\n\tresConfigWatch   io.Closer\n\tsrcipConfigWatch io.Closer\n\tdbConfigWatch    io.Closer\n\trelayConfigWatch io.Closer\n\tteeWatch         io.Closer\n\terrLoadConfig    = fmt.Errorf(\"config load error\")\n)\n\ntype ServerEtcdConfig struct {","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/server/config.go#L31-L67","documentation":"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.","triggerScenarios":"Thrown at endpoints/server/config.go:49 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Generate exactly 32 bytes of entropy and base64-encode it (openssl rand -base64 32)","Verify no characters were dropped or duplicated when pasting into config","If running multiple server instances that must share cookies, distribute the same corrected 32-byte key to all of them"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}