{"record":{"id":"551a78cd5d3d972f","repo":"juanfont/headscale","slug":"autogroup-not-supported-for-acl-sources","errorCode":null,"errorMessage":"autogroup not supported for ACL sources","messagePattern":"autogroup not supported for ACL sources","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hscontrol/policy/v2/types.go","lineNumber":137,"sourceCode":"\tErrTypeNotSupported            = errors.New(\"type not supported\")\n\tErrInvalidAlias                = errors.New(\"invalid alias format\")\n\tErrInvalidAutoApprover         = errors.New(\"invalid auto approver format\")\n\tErrInvalidOwner                = errors.New(\"invalid owner format\")\n\tErrGroupNotDefined             = errors.New(\"group not defined in policy\")\n\tErrInvalidGroupMember          = errors.New(\"invalid group member type\")\n\tErrGroupValueNotArray          = errors.New(\"group value must be an array of users\")\n\tErrInvalidHostIP               = errors.New(\"hostname contains invalid IP address\")\n\tErrTagNotDefined               = errors.New(\"tag not found\")\n\tErrAutoApproverNotAlias        = errors.New(\"auto approver is not an alias\")\n\tErrInvalidACLAction            = errors.New(\"invalid ACL action\")\n\tErrInvalidSSHAction            = errors.New(\"invalid SSH action\")\n\tErrInvalidProtocolNumber       = errors.New(\"invalid protocol number\")\n\tErrProtocolLeadingZero         = errors.New(\"leading 0 not permitted in protocol number\")\n\tErrProtocolOutOfRange          = errors.New(\"protocol number out of range (0-255)\")\n\tErrAutogroupNotSupported       = errors.New(\"autogroup not supported in headscale\")\n\tErrAutogroupInternetSrc        = errors.New(\"autogroup:internet can only be used in ACL destinations\")\n\tErrAutogroupSelfSrc            = errors.New(\"\\\"autogroup:self\\\" not valid on the src side of a rule\")\n\tErrAutogroupNotSupportedACLSrc = errors.New(\"autogroup not supported for ACL sources\")\n\tErrAutogroupNotSupportedACLDst = errors.New(\"autogroup not supported for ACL destinations\")\n\tErrAutogroupDangerAllDst       = errors.New(\"cannot use autogroup:danger-all as a dst\")\n\tErrAutogroupNotSupportedSSHSrc = errors.New(\"autogroup not supported for SSH sources\")\n\tErrAutogroupNotSupportedSSHDst = errors.New(\"autogroup not supported for SSH destinations\")\n\tErrHostNotDefined              = errors.New(\"host not defined in policy\")\n\tErrSSHSourceAliasNotSupported  = errors.New(\"alias not supported for SSH source\")\n\tErrSSHDestAliasNotSupported    = errors.New(\"alias not supported for SSH destination\")\n\tErrUnknownField                = errors.New(\"unknown field\")\n\tErrProtocolNoSpecificPorts     = errors.New(\"protocol does not support specific ports\")\n\tErrTestEmptyAssertions         = errors.New(\"test entry must have at least one of \\\"accept\\\" or \\\"deny\\\"\")\n\tErrTestProtocolNotAllowed      = errors.New(\"test protocol must be tcp, udp, sctp, or empty\")\n\tErrTestDestinationMultiPort    = errors.New(\"test destination port must be a single port\")\n\tErrTestDestinationCIDR         = errors.New(\"test destination must be a single host, not a CIDR range\")\n\tErrAutogroupInternetTestDst    = errors.New(\"autogroup:internet not valid as a test destination\")\n\tErrSSHTestEmptySrc             = errors.New(\"SSH tests entry must have a non-empty src\")\n\tErrSSHTestEmptyDst             = errors.New(\"SSH tests entry must have at least one dst\")\n\tErrSSHTestDstUnknownTag        = errors.New(\"SSH tests dst contains unknown tag\")\n\tErrSSHTestDstDisallowedElement = errors.New(\"SSH tests dst contains disallowed element\")","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/hscontrol/policy/v2/types.go#L119-L155","documentation":"Returned by validateAutogroupForSrc (hscontrol/policy/v2/types.go:2046) when an autogroup used as an ACL source is not in autogroupForSrc = {autogroup:member, autogroup:tagged, autogroup:danger-all} (types.go:1998). autogroup:internet and autogroup:self get their own specific errors first (2038/2042), so this fires for any other autogroup value that parses but is not a legal source.","triggerScenarios":"An ACL src containing an autogroup outside the allowed trio. With the current AutoGroup parse set, internet/self are special-cased and member/tagged/danger-all pass, so this is largely a forward-compatibility guard that activates when new autogroups are introduced. The error message embeds the allowed list.","commonSituations":"A future headscale version adds a new autogroup legal only in dst; older policies or early adopters using it in src will see this. Also from hand-crafted Go Policies with experimental autogroup values.","solutions":["Read the allowed list in the error message ('can be [autogroup:member autogroup:tagged autogroup:danger-all]') and use one of those on src","If you need 'all user-owned devices' use autogroup:member; 'all tagged devices' use autogroup:tagged; 'anything' use autogroup:danger-all","Move the unsupported autogroup to dst if that is its legal position"],"exampleFix":"// before\n{\"action\": \"accept\", \"src\": [\"autogroup:some-new-group\"], \"dst\": [\"tag:api:443\"]}\n\n// after\n{\"action\": \"accept\", \"src\": [\"autogroup:member\"], \"dst\": [\"tag:api:443\"]}","handlingStrategy":"validation","validationCode":"srcAutogroups := map[string]bool{\"autogroup:member\": true, \"autogroup:tagged\": true, \"autogroup:danger-all\": true}\nfor _, s := range acl.Src {\n\tif strings.HasPrefix(s, \"autogroup:\") && !srcAutogroups[s] {\n\t\treturn fmt.Errorf(\"%s not allowed as src\", s)\n\t}\n}","typeGuard":"func isAutogroupNotSupportedACLSrc(err error) bool {\n\treturn errors.Is(err, policy.ErrAutogroupNotSupportedACLSrc)\n}","tryCatchPattern":"if err := p.Validate(); err != nil {\n\tif errors.Is(err, policy.ErrAutogroupNotSupportedACLSrc) {\n\t\t// error message lists the legal src autogroups — follow it\n\t\treturn fmt.Errorf(\"illegal src autogroup: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Use only member/tagged/danger-all autogroups on src","Treat the allowed list printed in the error as authoritative per version","Review autogroup usage when upgrading headscale"],"tags":["policy","autogroup","acl","validation"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}