{"record":{"id":"54e9e50b22f3149f","repo":"hashicorp/nomad","slug":"acl-binding-rule-lookup-failed-v","errorCode":null,"errorMessage":"ACL binding rule lookup failed: %v","messagePattern":"ACL binding rule lookup failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/state/state_store_acl_binding_rule.go","lineNumber":87,"sourceCode":"\t// update has the auth method detailed in binding rule. Therefore, check\n\t// again while in our write txn.\n\tif !allowMissingAuthMethod {\n\t\tmethod, err := s.GetACLAuthMethodByName(nil, rule.AuthMethod)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"ACL auth method lookup failed: %v\", err)\n\t\t}\n\t\tif method == nil {\n\t\t\treturn false, fmt.Errorf(\"ACL binding rule insert failed: ACL auth method not found\")\n\t\t}\n\t}\n\n\t// This validation also happens within the RPC handler, but Raft latency\n\t// could mean that by the time the state call is invoked, another Raft\n\t// update has already written a method with the same name. We therefore\n\t// need to check we are not trying to create a rule with an existing ID.\n\texistingRaw, err := txn.First(TableACLBindingRules, indexID, rule.ID)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"ACL binding rule lookup failed: %v\", err)\n\t}\n\n\tvar existing *structs.ACLBindingRule\n\tif existingRaw != nil {\n\t\texisting = existingRaw.(*structs.ACLBindingRule)\n\t}\n\n\t// Depending on whether this is an initial create, or an update, we need to\n\t// check and set certain parameters. The most important is to ensure any\n\t// create index is carried over.\n\tif existing != nil {\n\n\t\t// If the rule already exists, check whether the update contains any\n\t\t// difference. If it doesn't, we can avoid a state update as well as\n\t\t// updates to any blocking queries.\n\t\tif existing.Equal(rule) {\n\t\t\treturn false, nil\n\t\t}","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/state/state_store_acl_binding_rule.go#L69-L105","documentation":"Returned by upsertACLBindingRuleTxn when the memdb lookup of an existing binding rule by ID fails (not when none exists). This check prevents accidental ID collisions before insert/update; the wrapped error indicates an internal lookup problem.","triggerScenarios":"txn.First(TableACLBindingRules, \"id\", rule.ID) erroring while applying UpsertACLBindingRules via Raft — schema/index mismatch or corrupted state store.","commonSituations":"Version skew between servers; state store corruption; memdb internal errors.","solutions":["Inspect the wrapped memdb error for the root cause.","Retry after ensuring consistent server versions.","Restore the state store from a snapshot if the error persists."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if rule.ID == \"\" { return errors.New(\"binding rule ID required\") }","typeGuard":null,"tryCatchPattern":"err := upsertRule(rule)\nif err != nil && strings.Contains(err.Error(), \"ACL binding rule lookup failed\") {\n    retryWithBackoff(upsertRule, rule)\n}","preventionTips":["Supply stable UUIDs for rule IDs","Keep servers version-aligned","Snapshot and monitor state-store health"],"tags":["nomad","state-store","acl","binding-rule","memdb"],"backgroundTag":"state-store-lookup-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}