{"record":{"id":"8c57a9df2a7239fe","repo":"hashicorp/nomad","slug":"acl-role-insert-failed-v","errorCode":null,"errorMessage":"ACL role insert failed: %v","messagePattern":"ACL role insert failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/state/state_store_acl.go","lineNumber":158,"sourceCode":"\tif existing != nil {\n\n\t\t// If the role already exists, check whether the update contains any\n\t\t// difference. If it doesn't, we can avoid a state update as wel as\n\t\t// updates to any blocking queries.\n\t\tif existing.Equal(role) {\n\t\t\treturn false, nil\n\t\t}\n\n\t\trole.CreateIndex = existing.CreateIndex\n\t\trole.ModifyIndex = index\n\t} else {\n\t\trole.CreateIndex = index\n\t\trole.ModifyIndex = index\n\t}\n\n\t// Insert the role into the table.\n\tif err := txn.Insert(TableACLRoles, role); err != nil {\n\t\treturn false, fmt.Errorf(\"ACL role insert failed: %v\", err)\n\t}\n\treturn true, nil\n}\n\n// validateACLRolePolicyLinksTxn is the same as ValidateACLRolePolicyLinks but\n// allows callers to pass their own transaction.\nfunc (s *StateStore) validateACLRolePolicyLinksTxn(txn *txn, role *structs.ACLRole) error {\n\tfor _, policyLink := range role.Policies {\n\t\t_, existing, err := txn.FirstWatch(\"acl_policy\", indexID, policyLink.Name)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"ACL policy lookup failed: %v\", err)\n\t\t}\n\t\tif existing == nil {\n\t\t\treturn errors.New(\"ACL policy not found\")\n\t\t}\n\t}\n\treturn nil\n}","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/state/state_store_acl.go#L140-L176","documentation":"Wraps an error returned by txn.Insert into the acl_roles table during upsertACLRoleTxn. The memdb insert failed for a low-level reason (invalid object, table/txn state), after uniqueness and policy-link validation already passed. The raft transaction aborts and no role is written.","triggerScenarios":"UpsertACLRoles / applyACLRolesDelete path when txn.Insert(TableACLRoles, role) errors — typically a malformed *structs.ACLRole (violating schema expectations) or a broken/expired transaction in an embedded or patched state store.","commonSituations":"Custom Nomad forks or enterprise patches that construct ACLRole objects incorrectly; corrupted memdb after a crash; test harnesses inserting invalid fixtures.","solutions":["Retry the operation; if via RPC, the CLI will surface the wrapped memdb message — retry after confirming leader stability.","Restart the server to rebuild the state store from raft.","Validate the ACLRole payload (ID, Name, Policies) conforms to the current structs.ACLRole schema for your Nomad version.","Check for Nomad version mismatches between server and any direct state-store manipulation (debug tooling).","File an upstream issue with the full wrapped error if reproducible."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Ensure the payload matches the SDK schema before sending.\nif role.Name == \"\" || role.ID == \"\" || len(role.Policies) == 0 { return errors.New(\"invalid ACLRole payload\") }","typeGuard":null,"tryCatchPattern":"_, _, err := client.ACL().Roles().Update(role, nil)\nif err != nil && strings.Contains(err.Error(), \"ACL role insert failed\") {\n    // retry with backoff; escalate to server restart if persistent\n}","preventionTips":["Use the official API client to construct ACLRole objects (schema-safe).","Keep servers on stock, supported Nomad versions.","Retry idempotent raft operations with backoff.","Watch for state-store corruption indicators in logs."],"tags":["nomad","state-store","memdb","acl"],"backgroundTag":"state-store-transaction-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"}