{"record":{"id":"4c6bc3309a58e2d8","repo":"wavetermdev/waveterm","slug":"error-decoding-jwt-private-key-w","errorCode":null,"errorMessage":"error decoding jwt private key: %w","messagePattern":"error decoding jwt private key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/wcore.go","lineNumber":201,"sourceCode":"\t\tkeyPair, err := wavejwt.GenerateKeyPair()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error generating jwt keypair: %w\", err)\n\t\t}\n\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)","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/wcore.go#L183-L219","documentation":"InitMainServer decodes MainServer.JwtPrivateKey from base64 (StdEncoding) before installing it into wavejwt. This error means the stored private key string is not valid standard base64, so startup aborts. It indicates the stored key data is corrupt or was written in a non-standard encoding.","triggerScenarios":"base64.StdEncoding.DecodeString(mainServer.JwtPrivateKey) fails because the DB field contains a non-base64 string — manual DB edits, truncation, whitespace/newlines (URL-safe or raw encoding instead of StdEncoding), or corruption from an interrupted write.","commonSituations":"Hand-editing wave.db; copying key values between environments with encoding changes; restoring a partially-written DB from backup; migration from a version that stored raw (non-base64) bytes.","solutions":["Delete the stored MainServer singleton (or wave.db) so InitMainServer regenerates a fresh key pair on next start","Verify the field is valid standard base64: `base64.StdEncoding.DecodeString(key)` in a scratch program; re-encode with StdEncoding if it was URL-safe","Strip whitespace/newlines from the stored value if present","Do not hand-edit the DB; instead clear the Jwt* fields to empty so they are regenerated"],"exampleFix":"// before: key stored URL-safe\nkey = base64.URLEncoding.EncodeToString(priv)\n// after: must be StdEncoding for this code path\nkey = base64.StdEncoding.EncodeToString(priv)","handlingStrategy":"validation","validationCode":"if _, err := base64.StdEncoding.DecodeString(mainServer.JwtPrivateKey); err != nil {\n    mainServer.JwtPrivateKey = \"\" // force regeneration path\n}","typeGuard":"func isValidB64Key(s string, size int) bool {\n    b, err := base64.StdEncoding.DecodeString(s)\n    return err == nil && len(b) == size\n}","tryCatchPattern":"if err := wcore.InitMainServer(); err != nil {\n    if strings.Contains(err.Error(), \"decoding jwt private key\") {\n        clearJwtKeysInDB() // blank fields; restart regenerates\n        return wcore.InitMainServer()\n    }\n    panic(err)\n}","preventionTips":["Never hand-edit wave.db key fields","Always encode keys with base64.StdEncoding","After decode, assert ed25519.PrivateKeySize (64) bytes","Back up the DB before upgrades/migrations"],"tags":["jwt","base64","corruption","key-decoding"],"backgroundTag":"invalid-base64-key","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}