{"record":{"id":"ed233c26435957e5","repo":"hashicorp/nomad","slug":"default-acl-auth-method-already-exists-v","errorCode":null,"errorMessage":"default ACL auth method already exists: %v","messagePattern":"default ACL auth method already exists: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/state/state_store_acl_sso.go","lineNumber":73,"sourceCode":"// to update the index table.\nfunc (s *StateStore) upsertACLAuthMethodTxn(index uint64, txn *txn, method *structs.ACLAuthMethod) (bool, error) {\n\n\t// Ensure the method hash is not zero to provide defense in depth. This\n\t// should be done outside the state store, so we do not spend time here and\n\t// thus Raft, when it can be avoided.\n\tif len(method.Hash) == 0 {\n\t\tmethod.SetHash()\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 or default\n\t// setting. We therefore need to check we are not trying to create a method\n\t// with an existing name or a duplicate default for the same type.\n\tif method.Default {\n\t\texistingMethodsDefaultMethod, _ := s.GetDefaultACLAuthMethod(nil)\n\t\tif existingMethodsDefaultMethod != nil && existingMethodsDefaultMethod.Name != method.Name {\n\t\t\treturn false, fmt.Errorf(\n\t\t\t\t\"default ACL auth method already exists: %v\", existingMethodsDefaultMethod.Name,\n\t\t\t)\n\t\t}\n\t}\n\texistingRaw, err := txn.First(TableACLAuthMethods, indexID, method.Name)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"ACL auth method lookup failed: %v\", err)\n\t}\n\n\tvar existing *structs.ACLAuthMethod\n\tif existingRaw != nil {\n\t\texisting = existingRaw.(*structs.ACLAuthMethod)\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 {","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/state/state_store_acl_sso.go#L55-L91","documentation":"When upserting an ACL auth method marked Default, the state store enforces that only one default method may exist per store: it queries GetDefaultACLAuthMethod and rejects the write if a different method is already default. The wrapped value is the name of the conflicting existing default method. Unlike the other errors here, this is a deliberate business-rule validation, not an internal failure.","triggerScenarios":"UpsertACLAuthMethods / upsertACLAuthMethodTxn receives an ACLAuthMethod with Default=true whose Name differs from the currently-stored default method's name.","commonSituations":"Running nomad acl auth-method create/update with -default on a cluster that already has another default method; IaC (Terraform) applying two default auth methods; copy-pasting a config where the default flag was left set.","solutions":["Run nomad acl auth-method list (or the API) to find the existing default method and decide which one should be default.","If the existing method should keep the flag, remove -default (Default=false) from your new/updated method and retry.","To switch the default, first update the existing method to Default=false, then upsert the new one with Default=true.","Fix your automation/config so only one method carries Default=true."],"exampleFix":"// before (CLI)\nnomad acl auth-method create -name=new-oidc -default -type=oidc ...\n// after\nnomad acl auth-method update -name=old-oidc -default=false\nnomad acl auth-method create -name=new-oidc -default -type=oidc ...","handlingStrategy":"validation","validationCode":"current, err := state.GetDefaultACLAuthMethod(nil)\nif err != nil {\n    return err\n}\nif method.Default && current != nil && current.Name != method.Name {\n    return fmt.Errorf(\"default auth method %q already exists; unset it first\", current.Name)\n}","typeGuard":"func isDuplicateDefaultErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"default ACL auth method already exists\")\n}","tryCatchPattern":"if err := upsertAuthMethod(m); err != nil {\n    if isDuplicateDefaultErr(err) {\n        // clear Default on the new method or unset the existing default, then retry\n        m.Default = false\n        return upsertAuthMethod(m)\n    }\n    return err\n}","preventionTips":["List existing auth methods and check which one is default before creating/updating with -default.","In IaC, make the default flag a single managed attribute across all auth methods.","To switch defaults, unset the old one before setting the new one.","Search the error text for the conflicting method name — it is included in the message."],"tags":["nomad","acl","auth-method","validation"],"backgroundTag":"duplicate-default-acl-auth-method","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}