{"record":{"id":"ec190964a09603a7","repo":"wavetermdev/waveterm","slug":"error-decoding-jwt-public-key-v","errorCode":null,"errorMessage":"error decoding jwt public key: %v","messagePattern":"error decoding jwt public key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/wsh/cmd/wshcmd-connserver.go","lineNumber":255,"sourceCode":"\n\t// setup the connserver rpc client first\n\tclient, bareRouteId, err := setupConnServerRpcClientWithRouter(router, sockName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error setting up connserver rpc client: %v\", err)\n\t}\n\twshfs.RpcClient = client\n\twshfs.RpcClientRouteId = bareRouteId\n\n\tlog.Printf(\"trying to get JWT public key\")\n\n\t// fetch and set JWT public key\n\tjwtPublicKeyB64, err := wshclient.GetJwtPublicKeyCommand(client, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting jwt public key: %v\", err)\n\t}\n\tjwtPublicKeyBytes, err := base64.StdEncoding.DecodeString(jwtPublicKeyB64)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error decoding jwt public key: %v\", err)\n\t}\n\terr = wavejwt.SetPublicKey(jwtPublicKeyBytes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error setting jwt public key: %v\", err)\n\t}\n\n\tlog.Printf(\"got JWT public key\")\n\n\t// now set up the domain socket\n\tunixListener, err := MakeRemoteUnixListener()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot create unix listener: %v\", err)\n\t}\n\tlog.Printf(\"unix listener started\")\n\tgo func() {\n\t\tdefer func() {\n\t\t\tpanichandler.PanicHandler(\"serverRunRouter:runListener\", recover())\n\t\t}()","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/cmd/wsh/cmd/wshcmd-connserver.go#L237-L273","documentation":"Returned by serverRunRouter when base64.StdEncoding.DecodeString fails on the JWT public key returned by the connserver. The key must be standard base64; a malformed payload means the server returned corrupt or unexpected data. Startup aborts because tokens cannot be validated without a valid key.","triggerScenarios":"The connserver returns a non-base64 or whitespace-padded string for jwtPublicKeyB64 — corrupted server state, a proxy mangling the response, or a client/server version mismatch changing the payload format (e.g. raw PEM instead of base64).","commonSituations":"Version skew where an older server sends a different encoding, manually edited or corrupted server key files, middleware/interceptors transforming the RPC payload, copy-pasted keys with newlines in test setups.","solutions":["Check what the connserver actually returns for the JWT public key and fix its key material/source","Ensure client and server wsh versions match (payload encoding contract changed between versions)","Regenerate the server's JWT key pair so a clean base64 key is served","As a defensive measure, tolerate whitespace/newlines by trimming or using base64.StdEncoding.DecodeString(strings.TrimSpace(...)) before failing"],"exampleFix":"// before\njwtPublicKeyBytes, err := base64.StdEncoding.DecodeString(jwtPublicKeyB64)\nif err != nil {\n    return fmt.Errorf(\"error decoding jwt public key: %v\", err)\n}\n// after\njwtPublicKeyBytes, err := base64.StdEncoding.DecodeString(strings.TrimSpace(jwtPublicKeyB64))\nif err != nil {\n    return fmt.Errorf(\"error decoding jwt public key: %v\", err)\n}","handlingStrategy":"type-guard","validationCode":"trimmed := strings.TrimSpace(jwtPublicKeyB64)\nif trimmed == \"\" {\n    return fmt.Errorf(\"connserver returned empty jwt public key\")\n}\nif _, err := base64.StdEncoding.DecodeString(trimmed); err != nil {\n    return fmt.Errorf(\"jwt public key is not valid std base64: %w\", err)\n}","typeGuard":"func isStdBase64(s string) bool {\n    _, err := base64.StdEncoding.DecodeString(strings.TrimSpace(s))\n    return err == nil && s != \"\"\n}","tryCatchPattern":"jwtPublicKeyBytes, err := base64.StdEncoding.DecodeString(jwtPublicKeyB64)\nif err != nil {\n    // fallback: try raw-pem or url-safe encodings before giving up\n    if pemBytes, _ := pem.Decode([]byte(jwtPublicKeyB64)); pemBytes != nil {\n        jwtPublicKeyBytes = pemBytes.Bytes\n    } else {\n        return fmt.Errorf(\"error decoding jwt public key: %v\", err)\n    }\n}","preventionTips":["Keep client and server versions in sync — key payload encoding is a contract","Never hand-edit or re-encode the server's JWT key material","Trim whitespace before decoding in defensive code paths","Validate the served key once at connserver startup, not only on the client"],"tags":["jwt","base64","encoding","startup"],"backgroundTag":"invalid-base64-data","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}