{"record":{"id":"c63bc06ddb4c9328","repo":"wavetermdev/waveterm","slug":"error-setting-jwt-public-key-w","errorCode":null,"errorMessage":"error setting jwt public key: %w","messagePattern":"error setting jwt public key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wcore/wcore.go","lineNumber":214,"sourceCode":"\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\n}\n","sourceCodeStart":196,"sourceCodeEnd":230,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wcore/wcore.go#L196-L230","documentation":"InitMainServer installs the public key via wavejwt.SetPublicKey. This error means the decoded bytes were rejected as an ed25519 public key (wrong size/format), preventing JWT verification from being configured and aborting startup.","triggerScenarios":"wavejwt.SetPublicKey(publicKeyBytes) returns an error because publicKeyBytes is not ed25519.PublicKeySize (32) bytes — a private key stored in the public-key field, truncation, or wrong-algorithm bytes.","commonSituations":"Swapped key fields in the DB; hand-pasted keys of the wrong type; partial DB corruption; migration from another key format.","solutions":["Clear both Jwt keys so a fresh pair is generated on next start","Verify the decoded public key is exactly 32 bytes; if it is 64 bytes the fields are swapped — exchange them","Regenerate with wavejwt.GenerateKeyPair and store each key StdEncoding-base64 encoded","Cross-check the wrapped error's expected-size message against your data"],"exampleFix":"// diagnose\nb, _ := base64.StdEncoding.DecodeString(mainServer.JwtPublicKey)\n// len(b) == 64 -> fields swapped\nmainServer.JwtPublicKey, mainServer.JwtPrivateKey = mainServer.JwtPrivateKey, mainServer.JwtPublicKey // then clear & regenerate if still failing","handlingStrategy":"validation","validationCode":"b, err := base64.StdEncoding.DecodeString(mainServer.JwtPublicKey)\nif err != nil || len(b) != ed25519.PublicKeySize {\n    mainServer.JwtPublicKey = \"\" // force regeneration\n}","typeGuard":"func isEd25519PublicKey(b []byte) bool { return len(b) == ed25519.PublicKeySize }","tryCatchPattern":"if err := wcore.InitMainServer(); err != nil {\n    if strings.Contains(err.Error(), \"setting jwt public key\") {\n        regenerateJwtKeys()\n        return wcore.InitMainServer()\n    }\n    panic(err)\n}","preventionTips":["Check decoded key length is 32 bytes (public) before install","If a 'public' key decodes to 64 bytes, fields are swapped — fix storage","Always regenerate both keys together","Validate keys after any DB restore or migration"],"tags":["jwt","ed25519","public-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"}