wavetermdev/waveterm · error
error decoding jwt public key: %v
Error message
error decoding jwt public key: %v
What it means
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.
Source
Thrown at cmd/wsh/cmd/wshcmd-connserver.go:255
// setup the connserver rpc client first
client, bareRouteId, err := setupConnServerRpcClientWithRouter(router, sockName)
if err != nil {
return fmt.Errorf("error setting up connserver rpc client: %v", err)
}
wshfs.RpcClient = client
wshfs.RpcClientRouteId = bareRouteId
log.Printf("trying to get JWT public key")
// fetch and set JWT public key
jwtPublicKeyB64, err := wshclient.GetJwtPublicKeyCommand(client, nil)
if err != nil {
return fmt.Errorf("error getting jwt public key: %v", err)
}
jwtPublicKeyBytes, err := base64.StdEncoding.DecodeString(jwtPublicKeyB64)
if err != nil {
return fmt.Errorf("error decoding jwt public key: %v", err)
}
err = wavejwt.SetPublicKey(jwtPublicKeyBytes)
if err != nil {
return fmt.Errorf("error setting jwt public key: %v", err)
}
log.Printf("got JWT public key")
// now set up the domain socket
unixListener, err := MakeRemoteUnixListener()
if err != nil {
return fmt.Errorf("cannot create unix listener: %v", err)
}
log.Printf("unix listener started")
go func() {
defer func() {
panichandler.PanicHandler("serverRunRouter:runListener", recover())
}()View on GitHub (pinned to a4447c1563)
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
Example fix
// before
jwtPublicKeyBytes, err := base64.StdEncoding.DecodeString(jwtPublicKeyB64)
if err != nil {
return fmt.Errorf("error decoding jwt public key: %v", err)
}
// after
jwtPublicKeyBytes, err := base64.StdEncoding.DecodeString(strings.TrimSpace(jwtPublicKeyB64))
if err != nil {
return fmt.Errorf("error decoding jwt public key: %v", err)
} Defensive patterns
Strategy: type-guard
Validate before calling
trimmed := strings.TrimSpace(jwtPublicKeyB64)
if trimmed == "" {
return fmt.Errorf("connserver returned empty jwt public key")
}
if _, err := base64.StdEncoding.DecodeString(trimmed); err != nil {
return fmt.Errorf("jwt public key is not valid std base64: %w", err)
} Type guard
func isStdBase64(s string) bool {
_, err := base64.StdEncoding.DecodeString(strings.TrimSpace(s))
return err == nil && s != ""
} Try / catch
jwtPublicKeyBytes, err := base64.StdEncoding.DecodeString(jwtPublicKeyB64)
if err != nil {
// fallback: try raw-pem or url-safe encodings before giving up
if pemBytes, _ := pem.Decode([]byte(jwtPublicKeyB64)); pemBytes != nil {
jwtPublicKeyBytes = pemBytes.Bytes
} else {
return fmt.Errorf("error decoding jwt public key: %v", err)
}
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- error getting jwt public key: %v
- failed to decode base64 data: %w
- error extracting socket name from %s: %v
- error generating jwt keypair: %w
- error decoding jwt private key: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/ec190964a09603a7.
Report an issue: GitHub.