wavetermdev/waveterm · error
MainServer claim not set
Error message
MainServer claim not set
What it means
The token itself is valid, but its claims lack MainServer=true, meaning the JWT was not issued by/for the main server in the job-manager trust model. The job manager requires this claim to accept peer authentication, rejecting tokens issued for other purposes.
Source
Thrown at pkg/jobmanager/mainserverconn.go:79
log.Printf("authenticateSelfToServer: failed to authenticate to server: %v\n", err)
return fmt.Errorf("failed to authenticate to server: %w", err)
}
msc.SelfAuthenticated.Store(true)
log.Printf("authenticateSelfToServer: successfully authenticated to server\n")
return nil
}
func (msc *MainServerConn) AuthenticateToJobManagerCommand(ctx context.Context, data wshrpc.CommandAuthenticateToJobData) error {
jobId, jobAuthToken := WshCmdJobManager.GetJobAuthInfo()
claims, err := wavejwt.ValidateAndExtract(data.JobAccessToken)
if err != nil {
log.Printf("AuthenticateToJobManager: failed to validate token: %v\n", err)
return fmt.Errorf("failed to validate token: %w", err)
}
if !claims.MainServer {
log.Printf("AuthenticateToJobManager: MainServer claim not set\n")
return fmt.Errorf("MainServer claim not set")
}
if claims.JobId != jobId {
log.Printf("AuthenticateToJobManager: JobId mismatch: expected %s, got %s\n", jobId, claims.JobId)
return fmt.Errorf("JobId mismatch")
}
msc.PeerAuthenticated.Store(true)
log.Printf("AuthenticateToJobManager: authentication successful for JobId=%s\n", claims.JobId)
err = msc.authenticateSelfToServer(jobAuthToken)
if err != nil {
msc.PeerAuthenticated.Store(false)
return err
}
WshCmdJobManager.SetAttachedClient(msc)
return nil
}
View on GitHub (pinned to a4447c1563)
Solutions
- Use a token issued by the main server that includes MainServer: true in its claims.
- Update both server and client to matching versions so token issuance includes the claim.
- Check the token-issuing code path to ensure wavejwt claims set MainServer.
Example fix
// before token := wavejwt.MakeToken(secret, claims) // claims missing MainServer // after claims.MainServer = true token := wavejwt.MakeToken(secret, claims)
Defensive patterns
Strategy: validation
Validate before calling
claims, err := wavejwt.ValidateAndExtract(token)
if err == nil && !claims.MainServer {
return fmt.Errorf("token lacks MainServer claim; use a main-server-issued job token")
} Try / catch
if err := conn.AuthenticateToJobManagerCommand(ctx, authData); err != nil {
if strings.Contains(err.Error(), "MainServer claim not set") {
return fmt.Errorf("wrong token type: request a job access token from the main server")
}
return err
} Prevention
- Use only tokens minted by the main server's job issuance path
- Keep server versions in sync so claim sets match
- Decode token claims locally to sanity-check before sending
When it happens
Trigger: AuthenticateToJobManagerCommand receives a valid JWT whose parsed claims have MainServer == false (token minted without the MainServer claim, or a different token type passed in).
Common situations: Passing a user/access token instead of a job access token, an older server version issuing tokens without the claim, or custom token issuance code omitting MainServer.
Related errors
- error authenticating with upstream: %v
- failed to validate token: %w
- JobId mismatch
- error getting jwt public key: %v
- failed to authenticate to server: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/8189ef9d9766768f.
Report an issue: GitHub.