wavetermdev/waveterm · error
error authenticating rpc connection: %v
Error message
error authenticating rpc connection: %v
What it means
The RPC transport is up, but the AuthenticateCommand RPC sent over the ControlRoute failed. Wave requires the client to prove its identity by presenting the JWT before any further RPCs are honored. Failures here indicate the server rejected the call (invalid/expired token), the response never arrived (timeout), or routing to the control endpoint failed.
Source
Thrown at pkg/waveapp/waveapp.go:186
return fmt.Errorf("error extracting rpc context from %s: %v", wshutil.WaveJwtTokenVarName, err)
}
client.RpcContext = rpcCtx
if client.RpcContext == nil || client.RpcContext.BlockId == "" {
return fmt.Errorf("no block id in rpc context")
}
client.ServerImpl = &WaveAppServerImpl{BlockId: client.RpcContext.BlockId, Client: client}
sockName, err := wshutil.ExtractUnverifiedSocketName(jwtToken)
if err != nil {
return fmt.Errorf("error extracting socket name from %s: %v", wshutil.WaveJwtTokenVarName, err)
}
rpcClient, err := wshutil.SetupDomainSocketRpcClient(sockName, client.ServerImpl, "vdomclient")
if err != nil {
return fmt.Errorf("error setting up domain socket rpc client: %v", err)
}
client.RpcClient = rpcClient
authRtnData, err := wshclient.AuthenticateCommand(client.RpcClient, jwtToken, &wshrpc.RpcOpts{Route: wshutil.ControlRoute})
if err != nil {
return fmt.Errorf("error authenticating rpc connection: %v", err)
}
if authRtnData.RouteId == "" {
return fmt.Errorf("authentication returned empty routeid")
}
client.RouteId = authRtnData.RouteId
return nil
}
func (c *Client) SetRootElem(elem *vdom.VDomElem) {
c.RootElem = elem
}
func (c *Client) CreateVDomContext(target *vdom.VDomTarget) error {
blockORef, err := wshclient.VDomCreateContextCommand(
c.RpcClient,
vdom.VDomCreateContext{Target: target},
&wshrpc.RpcOpts{Route: wshutil.MakeFeBlockRouteId(c.RpcContext.BlockId)},
)View on GitHub (pinned to a4447c1563)
Solutions
- Relaunch the app from a fresh Wave block to obtain a new JWT token and retry.
- Check clock synchronization on the host (token expiry is time-based).
- Confirm the Wave Terminal version matches the waveapp/wsh client libraries.
- Retry after verifying Wave is responsive (other wsh commands work in the block).
- Inspect the wrapped %v error for 'timeout' vs explicit rejection to pick between retry and re-auth.
Example fix
// before: single auth attempt with stale token
authRtnData, err := wshclient.AuthenticateCommand(client.RpcClient, jwtToken, &wshrpc.RpcOpts{Route: wshutil.ControlRoute})
// after: retry transient failures
var authRtnData *wshrpc.AuthRtnData
for i := 0; i < 3; i++ {
authRtnData, err = wshclient.AuthenticateCommand(client.RpcClient, jwtToken, &wshrpc.RpcOpts{Route: wshutil.ControlRoute})
if err == nil { break }
time.Sleep(time.Second)
} Defensive patterns
Strategy: retry
Validate before calling
if jwtToken == "" {
return fmt.Errorf("cannot authenticate: empty JWT token")
}
// ensure host clock is sane if tokens carry expiry claims Try / catch
authRtnData, err := wshclient.AuthenticateCommand(client.RpcClient, jwtToken, &wshrpc.RpcOpts{Route: wshutil.ControlRoute})
if err != nil {
if strings.Contains(err.Error(), "timeout") {
// transient: retry once with fresh client
}
return fmt.Errorf("error authenticating rpc connection: %v", err)
} Prevention
- Obtain the token fresh at each launch; JWTs expire.
- Keep host clocks synchronized (NTP).
- Keep Wave Terminal and wsh/waveapp library versions aligned.
- Retry transient timeouts; treat explicit rejection as requiring a new token.
When it happens
Trigger: Calling Connect when the JWT token has expired or was revoked, the control route is unreachable, the Wave host rejects the handshake, or the RPC times out because the Wave process is unresponsive.
Common situations: Long-running environments where the token TTL expired; system clock skew invalidating token timestamps; Wave busy/hung so the authentication response never returns; version mismatch where the server no longer accepts the client's auth payload shape.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- error getting jwt public key: %v
- error authenticating with upstream: %v
- failed to list workspaces: %v
- failed to list blocks from all %d workspace(s)
- reinstalling connection: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/ec03e1cf49978976.
Report an issue: GitHub.