wavetermdev/waveterm · error
error validating token: %w
Error message
error validating token: %w
What it means
AuthenticateCommand wraps any failure from ValidateAndExtractRpcContextFromToken (which parses the JWT and extracts the embedded RpcContext) with the message "error validating token: %w". The router received an auth token on a link but could not parse or validate it as a valid JWT carrying a usable RpcContext. The underlying cause is preserved via %w, so check the wrapped message (e.g. signature mismatch, malformed JWT, missing context claim).
Source
Thrown at pkg/wshutil/wshrouter_controlimpl.go:103
return nil
}
return fmt.Errorf("setpeerinfo only valid for proxy connections")
}
func (impl *WshRouterControlImpl) AuthenticateCommand(ctx context.Context, data string) (wshrpc.CommandAuthenticateRtnData, error) {
handler := GetRpcResponseHandlerFromContext(ctx)
if handler == nil {
return wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf("no response handler in context")
}
linkId := handler.GetIngressLinkId()
if linkId == baseds.NoLinkId {
return wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf("no ingress link found")
}
newCtx, err := ValidateAndExtractRpcContextFromToken(data)
if err != nil {
log.Printf("wshrouter authenticate error linkid=%d: %v", linkId, err)
return wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf("error validating token: %w", err)
}
routeId, err := validateRpcContextFromAuth(newCtx)
if err != nil {
return wshrpc.CommandAuthenticateRtnData{}, err
}
rtnData := wshrpc.CommandAuthenticateRtnData{RouteId: routeId}
if newCtx.IsRouter {
log.Printf("wshrouter authenticate success linkid=%d (router)", linkId)
impl.Router.trustLink(linkId, LinkKind_Router)
} else {
log.Printf("wshrouter authenticate success linkid=%d routeid=%q", linkId, routeId)
impl.Router.trustLink(linkId, LinkKind_Leaf)
impl.Router.bindRoute(linkId, routeId, true)
}
return rtnData, nil
}View on GitHub (pinned to a4447c1563)
Solutions
- Unwrap and read the inner error (Go: errors.Unwrap / %v of the result) to see whether the JWT is malformed, has a bad signature, or lacks the RpcContext claim.
- Obtain a fresh token from the root router / wave server (e.g. re-run the connection/token-swap flow) instead of reusing a cached one.
- Verify client and server are the same Wave Terminal version so the JWT claims (RpcContext shape) match.
- Check that the full, untruncated token string is passed as the Authenticate command data (no whitespace/newlines added by shell quoting).
Example fix
// before
err := client.Authenticate(ctx, os.Getenv("OLD_WAVETOKEN"))
// after
token := os.Getenv("WAVETERM_TOKEN")
if token == "" {
return fmt.Errorf("WAVETERM_TOKEN not set; get a fresh token from the wave server")
}
err := client.Authenticate(ctx, strings.TrimSpace(token)) Defensive patterns
Strategy: validation
Validate before calling
if token == "" || strings.ContainsAny(token, " \n\r\t") {
return fmt.Errorf("token empty or contains whitespace; re-mint before authenticating")
}
// optionally check JWT has 3 segments
if len(strings.Split(token, ".")) != 3 {
return fmt.Errorf("token is not a well-formed JWT")
} Try / catch
// Go
rtn, err := client.Authenticate(ctx, token)
if err != nil {
var wrappedErr error
if errors.Unwrap(err) != nil {
wrappedErr = errors.Unwrap(err)
log.Printf("token validation root cause: %v", wrappedErr)
}
return fmt.Errorf("authenticate failed: %w", err)
} Prevention
- Always fetch a fresh token from the server rather than caching across restarts
- Trim whitespace/newlines from tokens read from env vars or files
- Keep client and server Wave versions in sync
When it happens
Trigger: Calling AuthenticateCommand (via the wsh control RPC) with `data` set to a token string that is not a valid JWT, is signed with a different key than the router expects, has expired, or does not carry a parseable RpcContext claim.
Common situations: wsh clients connecting with a stale token after the server regenerated its keys; copy/paste truncating the JWT; a client built against a different Wave version encoding an incompatible RpcContext; env var WAVETERM_TOKEN pointing at an old token.
Related errors
- error getting jwt public key: %v
- error authenticating with upstream: %v
- error setting up rpc client: %w
- error making jwt token: %w
- error making jwt token: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/05c01fc59c2643ad.
Report an issue: GitHub.