{"record":{"id":"beedd521b557c5ec","repo":"hashicorp/nomad","slug":"at-least-one-policy-should-be-specified","errorCode":null,"errorMessage":"at least one policy should be specified","messagePattern":"at least one policy should be specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/acl.go","lineNumber":1022,"sourceCode":"}\n\n// Validate ensure the ACL role contains valid information which meets Nomad's\n// internal requirements. This does not include any state calls, such as\n// ensuring the linked policies exist.\nfunc (a *ACLRole) Validate() error {\n\n\tvar mErr multierror.Error\n\n\tif !ValidACLRoleName.MatchString(a.Name) {\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"invalid name '%s'\", a.Name))\n\t}\n\n\tif len(a.Description) > maxACLRoleDescriptionLength {\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"description longer than %d\", maxACLRoleDescriptionLength))\n\t}\n\n\tif len(a.Policies) < 1 {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"at least one policy should be specified\"))\n\t}\n\n\treturn mErr.ErrorOrNil()\n}\n\n// Canonicalize performs basic canonicalization on the ACL role object. It is\n// important for callers to understand certain fields such as ID are set if it\n// is empty, so copies should be taken if needed before calling this function.\nfunc (a *ACLRole) Canonicalize() {\n\tif a.ID == \"\" {\n\t\ta.ID = uuid.Generate()\n\t}\n}\n\n// Equal performs an equality check on the two service registrations. It\n// handles nil objects.\nfunc (a *ACLRole) Equal(o *ACLRole) bool {\n\tif a == nil || o == nil {","sourceCodeStart":1004,"sourceCodeEnd":1040,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/acl.go#L1004-L1040","documentation":"Appended by ACLRole.Validate when the role has no policy links (len(a.Policies) < 1); an ACL role is meaningless without at least one policy attached, so validation fails.","triggerScenarios":"POSTing an ACL role with policies: [] or omitted to the ACL role create/update API (ACL.UpsertRoles / ACLRole.Validate).","commonSituations":"Creating a role via the Nomad API or nomad acl role create without attaching any policy; templating tools that render an empty policies list; refactors that moved policies into roles but left the list empty pending later assignment.","solutions":["Add at least one policy (by name or ID) to the role's Policies field before submitting","Create the policy first, then the role referencing it","If a role genuinely has no permissions yet, delay creation until a policy is assigned"],"exampleFix":"// before\nrole := &api.ACLRole{Name: \"reader\", Policies: []*api.ACLRolePolicyLink{}}\n// after\nrole := &api.ACLRole{Name: \"reader\", Policies: []*api.ACLRolePolicyLink{{Name: \"read-only\"}}}","handlingStrategy":"validation","validationCode":"func validRole(r *structs.ACLRole) error {\n  if len(r.Policies) < 1 {\n    return errors.New(\"ACL role requires at least one policy\")\n  }\n  return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate policies exist before role submission","Check rendered templates for empty lists","Create policies first, then roles"],"tags":["nomad","acl","validation","role"],"backgroundTag":"acl-policy-required","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"}