hashicorp/nomad · error
ACL token expired
Error message
ACL token expired
What it means
ErrTokenExpired is a sentinel error in nomad/structs indicating the ACL token (or workload identity) presented has passed its expiration time. The servers return it during authentication when the token's ExpireTime is in the past (with a 2-second clock-skew allowance on the client side). It means the credential itself is structurally valid but no longer usable.
Source
Thrown at nomad/structs/errors.go:57
errRPCCodedErrorPrefix = "RPC Error:: " errDeploymentTerminalNoCancel = "can't cancel terminal deployment" errDeploymentTerminalNoFail = "can't fail terminal deployment" errDeploymentTerminalNoPause = "can't pause terminal deployment" errDeploymentTerminalNoPromote = "can't promote terminal deployment" errDeploymentTerminalNoResume = "can't resume terminal deployment" errDeploymentTerminalNoUnblock = "can't unblock terminal deployment" errDeploymentTerminalNoRun = "can't run terminal deployment" errDeploymentTerminalNoSetHealth = "can't set health of allocations for a terminal deployment" errDeploymentRunningNoUnblock = "can't unblock running deployment" ) var ( ErrNoLeader = errors.New(errNoLeader) ErrNotReadyForConsistentReads = errors.New(errNotReadyForConsistentReads) ErrNoRegionPath = errors.New(errNoRegionPath) ErrTokenNotFound = errors.New(errTokenNotFound) ErrTokenExpired = errors.New(errTokenExpired) ErrTokenInvalid = errors.New(errTokenInvalid) ErrPermissionDenied = errors.New(errPermissionDenied) ErrJobRegistrationDisabled = errors.New(errJobRegistrationDisabled) ErrNoNodeConn = errors.New(errNoNodeConn) ErrUnknownMethod = errors.New(errUnknownMethod) ErrUnknownNomadVersion = errors.New(errUnknownNomadVersion) ErrNodeLacksRpc = errors.New(errNodeLacksRpc) ErrMissingAllocID = errors.New(errMissingAllocID) ErrIncompatibleFiltering = errors.New(errIncompatibleFiltering) ErrMalformedChooseParameter = errors.New(errMalformedChooseParameter) // ErrResultPaginatorCreation is returned by list RPC handlers when the // result paginator cannot be built, for example when the server cannot // evaluate a requested filter expression. api.ResultPaginatorErrorContent // duplicates its message so the CLI can match it without importing structs. // Keep the two in sync. ErrResultPaginatorCreation = errors.New(errResultPaginatorCreation)
View on GitHub (pinned to 482b49bf1a)
Solutions
- Issue or obtain a fresh ACL token and retry the request
- Enable/configure token renewal if the client supports renewing short-lived tokens
- Use a non-expiring token for long-lived agents
- Synchronize clocks (NTP) if the token expired marginally earlier than expected
Example fix
// before client ACL set-token old-expired-token // after nomad acl token create -ttl=1h -policy=write nomad acl token update -accessor-id <accessor> -renew
Defensive patterns
Strategy: type-guard
Validate before calling
if token.ExpireTime != nil && token.ExpireTime.Before(time.Now()) {
// token already expired; request a new one before calling the API
} Type guard
func IsTokenExpired(t *api.ACLToken, now time.Time) bool {
return t != nil && t.ExpireTime != nil && t.ExpireTime.Before(now.Add(-2 * time.Second))
} Try / catch
acl, err := client.ACL().Info(token)
switch {
case errors.Is(err, structs.ErrTokenExpired):
token = renewOrCreateToken(); retry()
case err != nil:
return err
} Prevention
- Use non-expiring tokens for long-lived agents and CI workers
- Renew short-lived tokens on a schedule well before TTL expiry
- Monitor token ExpireTime and alert before expiry
- Keep clocks synchronized with NTP across clients and servers
When it happens
Trigger: Any RPC that authenticates via resolveTokenAndACL, Authenticate, resolveTokenFromSnapshotCache, or resolveSecretToken when the token/identity's IsExpired(now+2s) check is true — e.g. calling an API with a token created with a TTL that has elapsed.
Common situations: Long-running agents or CI jobs started with a short-lived ACL token or workload identity whose TTL expired mid-run; clock skew between client and servers (partially mitigated by the 2s skew buffer); tokens issued by Vault-style short-TTL workflows not being renewed.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- ACL token is invalid
- no signed workload identity available
- ACL policy not found
- ACL role not found
- detected corrupted token within the state store: missing rol
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/9186ad0b292f781d.
Report an issue: GitHub.