juanfont/headscale · error
nodeAttrs target does not support this autogroup
Error message
nodeAttrs target does not support this autogroup
What it means
Thrown by validateAutogroupForNodeAttrs (hscontrol/policy/v2/types.go:2082) when a nodeAttrs block targets an autogroup that cannot identify a stable set of nodes. Only autogroup:member and autogroup:tagged are valid nodeAttrs targets; autogroup:self, autogroup:internet, and autogroup:danger-all describe per-request or non-identity sets, so a node-level attribute cannot attach to them. The error message includes the offending value and the allowed list.
Source
Thrown at hscontrol/policy/v2/types.go:90
)
// Grant validation errors.
var (
ErrGrantMissingIPOrApp = errors.New("ip and app can not both be empty")
ErrGrantViaNotATag = errors.New("via can only be a tag")
ErrProtocolPortInvalidFormat = errors.New("expected only one colon in Internet protocol and port type")
ErrCapNameInvalidForm = errors.New("capability name must have the form {domain}/{path}")
ErrCapNameTailscaleDomain = errors.New("capability name must not be in the tailscale.com domain")
ErrGrantAutogroupSelfInvalidSource = errors.New("autogroup:self can only be used with users, groups, or supported autogroups")
ErrGrantAppWithAutogroupInternet = errors.New("cannot use app grants with autogroup:internet")
ErrGrantDefaultRouteCIDR = errors.New("to allow all IP addresses, use \"*\" or \"autogroup:internet\"")
)
// NodeAttrs validation errors.
var (
ErrNodeAttrsIPPoolReserved = errors.New("nodeAttrs ipPool must not overlap reserved Tailscale ranges")
ErrNodeAttrsIPPoolOutOfRange = errors.New("nodeAttrs ipPool must be within 100.64.0.0/10")
ErrNodeAttrsAutogroupNotAllowed = errors.New("nodeAttrs target does not support this autogroup")
ErrNodeAttrUnsupported = errors.New("nodeAttrs uses a feature headscale does not yet support")
ErrNodeAttrIPPoolUnsupported = errors.New("nodeAttrs ipPool requires the IP allocator (https://github.com/juanfont/headscale/issues/2912)")
ErrNodeAttrTargetUnsupported = errors.New("nodeAttrs target alias type is not supported")
)
// nodeAttrUnsupportedCaps lists caps that headscale parses but cannot act on
// today. Each entry maps to the tracking issue an operator can follow. The
// caps are accepted by Tailscale SaaS, but delivering them via headscale
// without the matching server-side machinery would be misleading — nodes
// would advertise a feature that does not work. Reject at policy load and
// point operators at the issue.
var nodeAttrUnsupportedCaps = map[tailcfg.NodeCapability]string{
tailcfg.NodeAttrFunnel: "https://github.com/juanfont/headscale/issues/2527",
}
// Policy validation errors.
var (
ErrInvalidUsername = errors.New("username must contain @")View on GitHub (pinned to 565fd254d0)
Solutions
- Change the nodeAttrs target to autogroup:member or autogroup:tagged
- If the attribute is per-user, attach it to explicit usernames or groups instead of an autogroup
- If you truly need self-scoped behaviour, express it via grants with autogroup:self rather than nodeAttrs
Example fix
// before
{"nodeAttrs": [{"target": ["autogroup:self"], "app": {"tailcfg-app-foo": ["*"]}}]}
// after
{"nodeAttrs": [{"target": ["autogroup:member"], "app": {"tailcfg-app-foo": ["*"]}}]} Defensive patterns
Strategy: validation
Validate before calling
// before compiling, check nodeAttrs targets
allowed := map[string]bool{"autogroup:member": true, "autogroup:tagged": true}
for _, na := range policy.NodeAttrs {
for _, t := range na.Target {
if strings.HasPrefix(t, "autogroup:") && !allowed[t] {
return fmt.Errorf("nodeAttrs target %q not allowed", t)
}
}
} Type guard
func isValidNodeAttrsAutogroup(s string) bool {
return s == "autogroup:member" || s == "autogroup:tagged"
} Try / catch
err := policy.Compile(...)
if errors.Is(err, policy.ErrNodeAttrsAutogroupNotAllowed) {
// report allowed targets from the message and fix the policy
} Prevention
- Only use autogroup:member/autogroup:tagged as nodeAttrs targets
- Run 'headscale policy check' in CI on every policy change
- Keep a lint step that whitelists autogroups per position
When it happens
Trigger: A policy (HuJSON/JSON ACL file or db-stored policy) containing e.g. {"nodeAttrs": [{"target": ["autogroup:self"], "attrs": [...]}]} fails at policy load/compile. Also triggered by autogroup:internet or autogroup:danger-all as a nodeAttrs target.
Common situations: Copying a Tailscale SaaS policy that uses autogroup:self or autogroup:internet in nodeAttrs; assuming any autogroup works anywhere an alias is accepted; upgrading from a policy format that tolerated these targets.
Related errors
- invalid autogroup
- test(s) failed
- autogroup:self destination requires source to contain only u
- tags in SSH source cannot access autogroup:member (user-owne
- username must contain @
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/6688ebc12f4924d2.
Report an issue: GitHub.