{"record":{"id":"fb5ab648ffa234a4","repo":"wavetermdev/waveterm","slug":"error-decoding-jwt-public-key-w","errorCode":null,"errorMessage":"error decoding jwt public key: %w","messagePattern":"error decoding jwt public key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/wcore.go","lineNumber":205,"sourceCode":"\t\tmainServer.JwtPrivateKey = base64.StdEncoding.EncodeToString(keyPair.PrivateKey)\n\t\tmainServer.JwtPublicKey = base64.StdEncoding.EncodeToString(keyPair.PublicKey)\n\t\tneedsUpdate = true\n\t}\n\n\tif needsUpdate {\n\t\terr = wstore.DBUpdate(ctx, mainServer)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error updating mainserver: %w\", err)\n\t\t}\n\t}\n\n\tprivateKeyBytes, err := base64.StdEncoding.DecodeString(mainServer.JwtPrivateKey)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error decoding jwt private key: %w\", err)\n\t}\n\tpublicKeyBytes, err := base64.StdEncoding.DecodeString(mainServer.JwtPublicKey)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error decoding jwt public key: %w\", err)\n\t}\n\n\terr = wavejwt.SetPrivateKey(privateKeyBytes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error setting jwt private key: %w\", err)\n\t}\n\terr = wavejwt.SetPublicKey(publicKeyBytes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error setting jwt public key: %w\", err)\n\t}\n\n\tpubKeyDer, err := x509.MarshalPKIXPublicKey(ed25519.PublicKey(publicKeyBytes))\n\tif err != nil {\n\t\tlog.Printf(\"warning: could not marshal public key for logging: %v\", err)\n\t} else {\n\t\tpubKeyPem := pem.EncodeToMemory(&pem.Block{\n\t\t\tType:  \"PUBLIC KEY\",\n\t\t\tBytes: pubKeyDer,","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/wcore.go#L187-L223","documentation":"Identical to the private-key case but for MainServer.JwtPublicKey: InitMainServer base64-decodes the stored public key and wraps any DecodeString failure. A non-standard-base64 or corrupt public key aborts startup.","triggerScenarios":"base64.StdEncoding.DecodeString(mainServer.JwtPublicKey) returns an error — the DB value is not valid standard base64 (wrong encoding variant, truncation, whitespace, manual edit, or interrupted write).","commonSituations":"Hand-edited or copy-pasted key values; restoring a truncated DB backup; version differences in how keys were serialized.","solutions":["Clear the Jwt* fields (or delete the singleton/DB) so a fresh key pair is generated on next start","Re-encode the public key with base64.StdEncoding and store it back","Check for and remove newlines/whitespace in the stored value","Validate the decoded length: an ed25519 public key must decode to exactly 32 bytes"],"exampleFix":"// sanity check before restart\nb, err := base64.StdEncoding.DecodeString(mainServer.JwtPublicKey)\nif err != nil || len(b) != ed25519.PublicKeySize {\n    mainServer.JwtPublicKey = \"\" // force regeneration\n}","handlingStrategy":"validation","validationCode":"if _, err := base64.StdEncoding.DecodeString(mainServer.JwtPublicKey); err != nil {\n    mainServer.JwtPublicKey = \"\" // force regeneration path\n}","typeGuard":"func isValidEd25519PubB64(s string) bool {\n    b, err := base64.StdEncoding.DecodeString(s)\n    return err == nil && len(b) == ed25519.PublicKeySize\n}","tryCatchPattern":"if err := wcore.InitMainServer(); err != nil {\n    if strings.Contains(err.Error(), \"decoding jwt public key\") {\n        clearJwtKeysInDB()\n        return wcore.InitMainServer()\n    }\n    panic(err)\n}","preventionTips":["Validate decoded public key is exactly 32 bytes before storing","Do not copy keys through editors that wrap/insert newlines","Use StdEncoding consistently, never URLEncoding, for stored keys","Clear both key fields together when regenerating"],"tags":["jwt","base64","public-key","corruption"],"backgroundTag":"invalid-base64-key","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}