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

  1. Use a token issued by the main server that includes MainServer: true in its claims.
  2. Update both server and client to matching versions so token issuance includes the claim.
  3. 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

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


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/8189ef9d9766768f. Report an issue: GitHub.