hashicorp/nomad · error

ACL token not found or invalid workload identity: %v

Error message

ACL token not found or invalid workload identity: %v

What it means

Returned by the HTTP server's ResolveToken (command/agent/http.go:420) when a request presents a secret (ACL token secretID or workload identity) that srv.Authenticate rejects on the server. The bearer token does not correspond to a known ACL token or valid workload identity on the resolved server, so the request is rejected.

Source

Thrown at command/agent/http.go:420

		s.listener.Close()
		<-s.listenerCh // block until http.Serve has returned.
	}
}

// ResolveToken extracts the ACL token secret ID from the request and
// translates it into an ACL object. Returns nil if ACLs are disabled.
func (s *HTTPServer) ResolveToken(req *http.Request) (*acl.ACL, error) {
	var secret string
	s.parseToken(req, &secret)

	var aclObj *acl.ACL
	var err error

	if srv := s.agent.Server(); srv != nil {
		r := &structs.GenericRequest{}
		r.AuthToken = secret
		if authErr := srv.Authenticate(nil, r); authErr != nil {
			return nil, fmt.Errorf("ACL token not found or invalid workload identity: %v", authErr)
		}

		aclObj, err = srv.ResolveACL(r)
	} else {
		// Not a Server, so use the Client for token resolution. Note
		// this gets forwarded to a server with AllowStale = true if
		// the local ACL cache TTL has expired (30s by default)
		aclObj, err = s.agent.Client().ResolveToken(secret)
	}

	if err != nil {
		return nil, fmt.Errorf("failed to resolve ACL token: %v", err)
	}

	return aclObj, nil
}

// registerHandlers is used to attach our handlers to the mux

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the token exists on this cluster: `nomad acl token self -secret=<id>`.
  2. Create a new token with `nomad acl token create` and update X-Nomad-Token / NOMAD_TOKEN.
  3. Check NOMAD_ADDR/NOMAD_REGION — you may be authenticating against a different cluster.
  4. For workload identities, confirm the identity name and that the JWT is passed unmodified.
  5. Purge stale credentials from CI/env and re-authenticate.

Example fix

// before
export NOMAD_TOKEN=stale-deleted-secret-id
nomad agent-info
// after: verify and use a live token
nomad acl token list
export NOMAD_TOKEN=<valid-secret-id>
nomad agent-info
Defensive patterns

Strategy: validation

Validate before calling

out, err := exec.Command("nomad", "acl", "token", "self", "-secret", secret).CombinedOutput()
if err != nil {
    return fmt.Errorf("token invalid on this cluster: %s", out)
}

Try / catch

if err != nil {
    if strings.Contains(err.Error(), "ACL token not found or invalid workload identity") {
        // mint a new token via nomad acl token create and retry once
    }
}

Prevention

When it happens

Trigger: Any authenticated API request (agent self/reload/host, jobs parse) with Authorization: Bearer or X-Nomad-Token whose secretID was deleted/expired, belongs to a different cluster/region, or is a workload identity JWT the server cannot validate while ACLs are enabled.

Common situations: Token rotation with clients caching old secretIDs; pointing clients at the wrong cluster; stale NOMAD_TOKEN in env/CI; truncated tokens from copy-paste; misconfigured workload identities in job templates.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/8407fb3743aa6563. Report an issue: GitHub.