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, nil

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set policy.Name to a non-empty string before calling Upsert.
  2. Validate policy and policy.Name != "" at the call site before invoking Upsert.
  3. Check that the source config/JSON actually contains the policy name field with the correct key.
  4. 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

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


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