hashicorp/nomad · error
missing policy name
Error message
missing policy name
What it means
SentinelPolicies.Upsert validates its input before issuing the PUT /v1/sentinel/policy/<name> request. If the policy pointer is nil or the policy's Name field is empty, the client refuses to build a URL path with a blank name and returns this error locally, without any server round-trip.
Source
Thrown at api/sentinel.go:33
// SentinelPolicies returns a new handle on the Sentinel policies.
func (c *Client) SentinelPolicies() *SentinelPolicies {
return &SentinelPolicies{client: c}
}
// List is used to dump all of the policies.
func (a *SentinelPolicies) List(q *QueryOptions) ([]*SentinelPolicyListStub, *QueryMeta, error) {
var resp []*SentinelPolicyListStub
qm, err := a.client.query("/v1/sentinel/policies", &resp, q)
if err != nil {
return nil, nil, err
}
return resp, qm, nil
}
// Upsert is used to create or update a policy
func (a *SentinelPolicies) Upsert(policy *SentinelPolicy, q *WriteOptions) (*WriteMeta, error) {
if policy == nil || policy.Name == "" {
return nil, errors.New("missing policy name")
}
wm, err := a.client.put("/v1/sentinel/policy/"+policy.Name, policy, nil, q)
if err != nil {
return nil, err
}
return wm, nil
}
// Delete is used to delete a policy
func (a *SentinelPolicies) Delete(policyName string, q *WriteOptions) (*WriteMeta, error) {
if policyName == "" {
return nil, errors.New("missing policy name")
}
wm, err := a.client.delete("/v1/sentinel/policy/"+policyName, nil, nil, q)
if err != nil {
return nil, err
}
return wm, nilView on GitHub (pinned to 482b49bf1a)
Solutions
- Set policy.Name to a non-empty string before calling Upsert.
- Validate policy and policy.Name != "" at the call site before invoking Upsert.
- Check that the source config/JSON actually contains the policy name field with the correct key.
- For delete-after-upsert flows, ensure the delete uses the same non-empty name.
Example fix
// before
client.SentinelPolicies().Upsert(&SentinelPolicy{Rules: rules}, nil)
// after
client.SentinelPolicies().Upsert(&SentinelPolicy{Name: "deny-privileged", Rules: rules}, nil) Defensive patterns
Strategy: validation
Validate before calling
func canUpsert(p *api.SentinelPolicy) bool {
return p != nil && p.Name != ""
}
if !canUpsert(policy) { return fmt.Errorf("sentinel policy requires a name") } Type guard
func hasName(p *api.SentinelPolicy) bool {
return p != nil && p.Name != ""
} Try / catch
if !hasName(policy) {
return fmt.Errorf("policy.Name must be set before Upsert")
}
_, err := client.SentinelPolicies().Upsert(policy, nil)
if err != nil { return fmt.Errorf("upsert sentinel policy %q: %w", policy.Name, err) } Prevention
- Always populate SentinelPolicy.Name before calling Upsert.
- Validate policy structs parsed from config files immediately after decoding.
- Add unit tests covering upsert with an empty-name policy.
- Wrap upsert calls to return the intended policy name in error messages.
When it happens
Trigger: Calling SentinelPolicies().Upsert(&SentinelPolicy{}, q) with Name unset, or Upsert(nil, q), or constructing a SentinelPolicy by deserializing config where the 'name' key was absent/misspelled.
Common situations: Terraform/CLI tooling building Sentinel policies from YAML/HCL where the name field is optional or mistyped; code that upserts a policy parsed from a file whose metadata section failed to parse.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Unknown log level
- command is not present
- unknown task name %q
- must provide a valid alloc id
- must provide a file path
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/89072ff08ee440f3.
Report an issue: GitHub.