hashicorp/nomad · error

namespace must be set to set job ID

Error message

namespace must be set to set job ID

What it means

When an ACL policy includes a JobACL block, Validate requires Namespace to be set whenever JobID is set. A job-scoped policy is meaningless without a namespace, so Nomad rejects the policy with 'namespace must be set to set job ID'. The error is aggregated into the policy's multierror.

Source

Thrown at nomad/structs/acl.go:384

}

func (a *ACLPolicy) Validate() error {
	var mErr multierror.Error
	if !ValidPolicyName.MatchString(a.Name) {
		err := fmt.Errorf("invalid name '%s'", a.Name)
		mErr.Errors = append(mErr.Errors, err)
	}
	if _, err := acl.Parse(a.Rules, acl.PolicyParseStrict); err != nil {
		err = fmt.Errorf("failed to parse rules: %v", err)
		mErr.Errors = append(mErr.Errors, err)
	}
	if len(a.Description) > maxPolicyDescriptionLength {
		err := fmt.Errorf("description longer than %d", maxPolicyDescriptionLength)
		mErr.Errors = append(mErr.Errors, err)
	}
	if a.JobACL != nil {
		if a.JobACL.JobID != "" && a.JobACL.Namespace == "" {
			err := fmt.Errorf("namespace must be set to set job ID")
			mErr.Errors = append(mErr.Errors, err)
		}
		if a.JobACL.Group != "" && a.JobACL.JobID == "" {
			err := fmt.Errorf("job ID must be set to set group")
			mErr.Errors = append(mErr.Errors, err)
		}
		if a.JobACL.Task != "" && a.JobACL.Group == "" {
			err := fmt.Errorf("group must be set to set task")
			mErr.Errors = append(mErr.Errors, err)
		}
	}

	return mErr.ErrorOrNil()
}

// ACLPolicyListStub is used to for listing ACL policies
type ACLPolicyListStub struct {
	Name        string

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set JobACL.Namespace (e.g. "default") whenever JobACL.JobID is provided.
  2. Review the policy JSON sent to /v1/acl/policy and ensure namespace is populated.
  3. If using nomad acl policy apply templating, verify the namespace placeholder resolves to a real value.
  4. Prefer always authoring the full JobACL triple (namespace, job ID) to avoid partial objects.

Example fix

// before
"JobACL": {"JobID": "webapp"}
// after
"JobACL": {"Namespace": "default", "JobID": "webapp"}
Defensive patterns

Strategy: validation

Validate before calling

func validateJobACL(j *JobACL) error {
    if j != nil && j.JobID != "" && j.Namespace == "" {
        return errors.New("namespace must be set when JobID is set")
    }
    return nil
}

Type guard

func jobACLComplete(j *structs.JobACL) bool {
    return j == nil || j.JobID == "" || j.Namespace != ""
}

Try / catch

if err := policy.Validate(); err != nil {
    if strings.Contains(err.Error(), "namespace must be set to set job ID") {
        policy.JobACL.Namespace = "default"
    }
    return policy.Validate()
}

Prevention

When it happens

Trigger: Creating/updating an ACL policy whose JobACL.JobID is non-empty while JobACL.Namespace is empty (JSON API submit or the -job / templated flags in `nomad acl policy apply` that omitted namespace).

Common situations: Hand-crafting the JSON policy with only {"JobID":"myjob"}; API clients defaulting namespace to empty string instead of 'default'; templates that conditionally render namespace only when it differs from default.

Related errors


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