hashicorp/nomad · error

Invalid policy: %s

Error message

Invalid policy: %s

What it means

acl/policy.go:565 (Parse) returns 'Invalid policy: %s' (with the raw policy text) when the policy decodes as valid HCL but parses to an empty policy (p.IsEmpty()) — i.e., it contains no actual rules. Nomad refuses to store rule-less policies because they would be meaningless placeholders.

Source

Thrown at acl/policy.go:565

// constants PolicyParseStrict and PolicyParseLenient can be used to make the
// intent clear at the call site.
func Parse(rules string, strict bool) (*Policy, error) {
	// Decode the rules
	p := &Policy{Raw: rules}
	if rules == "" {
		// Hot path for empty rules
		return p, nil
	}

	// Attempt to parse
	if err := hclDecode(p, rules); err != nil {
		return nil, fmt.Errorf("Failed to parse ACL Policy: %v", err)
	}

	// At least one valid policy must be specified, we don't want to store only
	// raw data
	if p.IsEmpty() {
		return nil, fmt.Errorf("Invalid policy: %s", p.Raw)
	}

	// Validate the policy
	for _, ns := range p.Namespaces {
		if !validNamespace.MatchString(ns.Name) {
			return nil, fmt.Errorf("Invalid namespace name: %#v", ns)
		}
		if ns.Policy != "" && !isPolicyValid(ns.Policy) {
			return nil, fmt.Errorf("Invalid namespace policy: %#v", ns)
		}
		for _, cap := range ns.Capabilities {
			if !isNamespaceCapabilityValid(cap) {
				return nil, fmt.Errorf("Invalid namespace capability '%s': %#v", cap, ns)
			}
		}

		// Expand the short hand policy to the capabilities and
		// add to any existing capabilities

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Include at least one real rule stanza (namespace/node/service/host_volume/variables etc.) in the policy
  2. Fix the templating pipeline that produced an empty/whitespace-only rules document
  3. Verify with nomad acl policy apply after ensuring the file has actual content

Example fix

// before
# only comments in rules.hcl
# namespace "default" { ... }
// after
namespace "default" {
  policy = "read"
}
Defensive patterns

Strategy: validation

Validate before calling

// ensure the policy has at least one rule before submitting
if strings.TrimSpace(stripComments(rules)) == "" { return errors.New("policy has no rules") }

Try / catch

if _, err := acl.ParsePolicy(rules); err != nil {
    if strings.HasPrefix(err.Error(), "Invalid policy:") {
        return fmt.Errorf("rules file rendered empty — check templates: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Applying an ACL policy whose rules contain only comments, whitespace, or empty stanzas; a template/variable interpolation that evaluated to nothing; passing an empty or comments-only rules file to nomad acl policy apply.

Common situations: CI pipelines templating policies where variables were empty, yielding comments-only output; truncation of the rules file upstream; accidentally applying an example file that documents policy format only in comments.

Related errors


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