hashicorp/nomad · error

ACL binding rule not found

Error message

ACL binding rule not found

What it means

deleteACLBindingRuleTxn looks up an ACL binding rule by ID in the acl_binding_rules table before deleting it. A nil lookup result yields "ACL binding rule not found" so deletes are strict rather than silently idempotent. The error surfaces through DeleteACLBindingRules to the ACLBindingRule.Delete RPC.

Solutions

  1. Run nomad acl binding-rule list to verify the rule ID before deleting.
  2. Make automation idempotent: ignore the not-found error when the target state is 'rule absent'.
  3. Confirm you are targeting the correct region/cluster holding the rule.

Example fix

// before
client.ACLBindingRules().Delete(ruleID, nil)
// after
err := client.ACLBindingRules().Delete(ruleID, nil)
if err != nil && !strings.Contains(err.Error(), "not found") {
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

_, _, err := client.ACLBindingRules().Get(ruleID, nil)
if err != nil {
    return nil // rule already absent
}

Try / catch

err := client.ACLBindingRules().Delete(ruleID, nil)
if err != nil && strings.Contains(err.Error(), "ACL binding rule not found") {
    return nil // idempotent delete
}

Prevention

When it happens

Trigger: ACLBindingRule.Delete RPC (nomad acl binding-rule delete <id>) with an ID that does not exist; racing duplicate deletes; IDs from a different cluster or already-removed rule.

Common situations: Automation cleaning up SSO binding rules with stale IDs; re-running a provisioner that already deleted the rule; copy-pasted ID from another environment.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at nomad/state/state_store_acl_binding_rule.go:153

	// Update the index table to indicate an update has occurred.
	if err := txn.Insert(tableIndex, &IndexEntry{TableACLBindingRules, index}); err != nil {
		return fmt.Errorf("index update failed: %v", err)
	}

	return txn.Commit()
}

// deleteACLBindingRuleTxn deletes a single ACL binding rule from the state
// store using the provided write transaction. It is the responsibility of the
// caller to update the index table.
func (s *StateStore) deleteACLBindingRuleTxn(txn *txn, ruleID string) error {
	existing, err := txn.First(TableACLBindingRules, indexID, ruleID)
	if err != nil {
		return fmt.Errorf("ACL binding rule lookup failed: %v", err)
	}
	if existing == nil {
		return errors.New("ACL binding rule not found")
	}

	// Delete the existing entry from the table.
	if err := txn.Delete(TableACLBindingRules, existing); err != nil {
		return fmt.Errorf("ACL binding rule deletion failed: %v", err)
	}
	return nil
}

// GetACLBindingRules returns an iterator that contains all ACL binding rules
// stored within state.
func (s *StateStore) GetACLBindingRules(ws memdb.WatchSet) (memdb.ResultIterator, error) {
	txn := s.db.ReadTxn()

	// Walk the entire table to get all ACL binding rules.
	iter, err := txn.Get(TableACLBindingRules, indexID)
	if err != nil {
		return nil, fmt.Errorf("ACL binding rules lookup failed: %v", err)

View on GitHub (pinned to 482b49bf1a)