{"record":{"id":"1505bc4c84053342","repo":"wavetermdev/waveterm","slug":"error-setting-jwt-private-key-w","errorCode":null,"errorMessage":"error setting jwt private key: %w","messagePattern":"error setting jwt private key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/wcore.go","lineNumber":210,"sourceCode":"\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,\n\t\t})\n\t\tlog.Printf(\"JWT Public Key:\\n%s\", string(pubKeyPem))\n\t}\n\n\treturn nil","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/wcore.go#L192-L228","documentation":"After decoding, InitMainServer installs the private key into the wavejwt package via wavejwt.SetPrivateKey. This error means the decoded bytes were rejected — most commonly they are not a valid ed25519 private key (wrong length), so JWT signing cannot be initialized.","triggerScenarios":"wavejwt.SetPrivateKey(privateKeyBytes) returns an error because privateKeyBytes is not ed25519.PrivateKeySize (64) bytes — the stored value decodes but holds a public key, a truncated key, or bytes from a different algorithm.","commonSituations":"Swapped public/private fields in the DB; keys from an older/other key scheme; manually regenerated keys of the wrong size; partial corruption.","solutions":["Clear both JwtPrivateKey and JwtPublicKey so InitMainServer generates a fresh ed25519 pair","Check lengths after decode: private key must be 64 bytes, public key 32 bytes; swap the fields if they were reversed","Regenerate keys with wavejwt.GenerateKeyPair and store them base64(StdEncoding)-encoded","Check the wrapped error message for the expected key size and compare with your stored data"],"exampleFix":"// before\nmainServer.JwtPrivateKey = base64.StdEncoding.EncodeToString(pubBytes)\n// after\nkeyPair, _ := wavejwt.GenerateKeyPair()\nmainServer.JwtPrivateKey = base64.StdEncoding.EncodeToString(keyPair.PrivateKey)","handlingStrategy":"validation","validationCode":"b, err := base64.StdEncoding.DecodeString(mainServer.JwtPrivateKey)\nif err != nil || len(b) != ed25519.PrivateKeySize {\n    mainServer.JwtPrivateKey = \"\" // force regeneration\n}","typeGuard":"func isEd25519PrivateKey(b []byte) bool { return len(b) == ed25519.PrivateKeySize }","tryCatchPattern":"if err := wcore.InitMainServer(); err != nil {\n    if strings.Contains(err.Error(), \"setting jwt private key\") {\n        regenerateJwtKeys() // wavejwt.GenerateKeyPair + store\n        return wcore.InitMainServer()\n    }\n    panic(err)\n}","preventionTips":["Check decoded key length is 64 bytes (private) before install","Don't swap public/private fields when editing storage","Generate keys only via wavejwt.GenerateKeyPair","Regenerate the pair as a unit, never one key alone"],"tags":["jwt","ed25519","private-key","key-format"],"backgroundTag":"invalid-jwt-signing-key","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}