hashicorp/nomad · error
Permission denied
Error message
Permission denied
What it means
ErrPermissionDenied is the generic sentinel error for ACL authorization failures in Nomad. It is returned when an authenticated token simply lacks the required capability — for example when AllowAgentWrite fails on the agent endpoint (command/agent/agent_endpoint.go / client/agent_endpoint.go:41). It is distinct from invalid/expired tokens: the token is valid but insufficiently privileged.
Source
Thrown at nomad/structs/errors.go:59
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) ErrUnknownNode = errors.New(ErrUnknownNodePrefix)
View on GitHub (pinned to 482b49bf1a)
Solutions
- Attach a policy granting the required capability (e.g. 'agent write', node/alloc write) to the token
- Create a new token with the management policy for administrative operations
- Inspect effective policy via 'nomad acl token inspect' / 'nomad acl policy info' to confirm capabilities
- Ensure the request targets the right namespace/region the policy covers
Example fix
// before
nomad acl token create -policy=read-only // then attempt agent write -> ErrPermissionDenied
// after
nomad acl policy apply agent-write agent-write.hcl // includes: agent { policy = "write" }
nomad acl token create -policy=agent-write Defensive patterns
Strategy: type-guard
Validate before calling
// pre-check capability before the call
if !aclObj.AllowAgentWrite() {
return errors.New("token lacks agent write capability")
} Type guard
func IsPermissionDenied(err error) bool {
return errors.Is(err, structs.ErrPermissionDenied)
} Try / catch
err := doRequest()
if errors.Is(err, structs.ErrPermissionDenied) {
// request a token with the required policy or surface a clear authz error
} Prevention
- Grant least-privilege policies explicitly listing needed capabilities
- Test tokens with 'nomad acl token inspect' before wiring into automation
- Separate read and write tokens per workload
- Keep namespace/region scopes in policies aligned with actual usage
When it happens
Trigger: Calling an authenticated endpoint whose required ACL capability is not granted: e.g. agent write endpoints when aclObj.AllowAgentWrite() is false; any handler whose ResolveToken / policy evaluation yields a deny decision.
Common situations: Tokens created with read-only policies being used for write operations; a client agent endpoint hit by an unprivileged caller; test fixtures (TestClient_ACL_ResolveToken) deliberately using bad tokens to assert denial.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- plugin not executable
- ACL policy not found
- ACL role not found
- detected corrupted token within the state store: missing rol
- ACL binding rule not found
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/ad9f94c461e33043.
Report an issue: GitHub.