wavetermdev/waveterm · error

failed to verify job auth token: %w

Error message

failed to verify job auth token: %w

What it means

The forwarded Command_AuthenticateJobManagerVerify request to the control root failed. The underlying RPC error is wrapped; causes include the root rejecting the job/token (invalid token, unknown job) or transport/routing failures.

Source

Thrown at pkg/wshutil/wshrouter_controlimpl.go:280

		job, err := wstore.DBMustGet[*waveobj.Job](ctx, data.JobId)
		if err != nil {
			log.Printf("wshrouter authenticate-jobmanager error linkid=%d jobid=%q: failed to get job: %v", linkId, data.JobId, err)
			return fmt.Errorf("failed to get job: %w", err)
		}

		if job.JobAuthToken != data.JobAuthToken {
			log.Printf("wshrouter authenticate-jobmanager error linkid=%d jobid=%q: invalid jobauthtoken", linkId, data.JobId)
			return fmt.Errorf("invalid jobauthtoken")
		}
	} else {
		wshRpc := GetWshRpcFromContext(ctx)
		if wshRpc == nil {
			return fmt.Errorf("no wshrpc in context")
		}
		_, err := wshRpc.SendRpcRequest(wshrpc.Command_AuthenticateJobManagerVerify, data, &wshrpc.RpcOpts{Route: ControlRootRoute})
		if err != nil {
			log.Printf("wshrouter authenticate-jobmanager error linkid=%d jobid=%q: failed to verify job auth token: %v", linkId, data.JobId, err)
			return fmt.Errorf("failed to verify job auth token: %w", err)
		}
	}

	routeId := MakeJobRouteId(data.JobId)
	log.Printf("wshrouter authenticate-jobmanager success linkid=%d jobid=%q routeid=%q", linkId, data.JobId, routeId)
	impl.Router.trustLink(linkId, LinkKind_Leaf)
	impl.Router.bindRoute(linkId, routeId, true)

	return nil
}

func validateRpcContextFromAuth(newCtx *wshrpc.RpcContext) (string, error) {
	if newCtx == nil {
		return "", fmt.Errorf("no context found in jwt token")
	}
	if newCtx.IsRouter && newCtx.RouteId != "" {
		return "", fmt.Errorf("invalid context, router cannot have a routeid")
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check the wrapped error to see whether the root rejected the token or the route failed
  2. Verify connectivity to the control root and retry authentication
  3. Re-sync job credentials so the root's stored token matches what the client sends

Example fix

// before
// retry blindly with the same token
// after
job, _ := wstore.DBGet[*waveobj.Job](ctx, jobId)
if job.JobAuthToken != token { /* refresh token before retrying verify */ }
Defensive patterns

Strategy: retry

Validate before calling

// no pre-call check possible; ensure the root route is registered
if !router.HasRoute(wshutil.ControlRootRoute) {
    return fmt.Errorf("control root route unavailable")
}

Try / catch

err := impl.AuthenticateJobManagerCommand(ctx, data)
if err != nil && strings.Contains(err.Error(), "failed to verify job auth token") {
    // inspect wrapped cause; retry after reconnecting to control root
}

Prevention

When it happens

Trigger: Non-root router calling SendRpcRequest(Command_AuthenticateJobManagerVerify, ..., Route: ControlRootRoute) and the RPC returns an error.

Common situations: Root rejected the token (invalid jobauthtoken upstream); ControlRootRoute unreachable because the link to the root is down; timeouts.

Related errors


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