juanfont/headscale · error · ErrAutogroupInternetTestDst

autogroup:internet not valid as a test destination

Error message

autogroup:internet not valid as a test destination

What it means

ErrAutogroupInternetTestDst is returned by validateTestDestination (hscontrol/policy/v2/types.go:3251) when a tests-block destination is autogroup:internet. Internet access is enforced via exit-node routing (AllowedIPs on tailcfg.Node), not the packet filter, so the tests engine cannot give a single allow/deny answer for it. autogroup:internet remains valid as an ACL/grant destination only.

Source

Thrown at hscontrol/policy/v2/types.go:151

	ErrProtocolOutOfRange          = errors.New("protocol number out of range (0-255)")
	ErrAutogroupNotSupported       = errors.New("autogroup not supported in headscale")
	ErrAutogroupInternetSrc        = errors.New("autogroup:internet can only be used in ACL destinations")
	ErrAutogroupSelfSrc            = errors.New("\"autogroup:self\" not valid on the src side of a rule")
	ErrAutogroupNotSupportedACLSrc = errors.New("autogroup not supported for ACL sources")
	ErrAutogroupNotSupportedACLDst = errors.New("autogroup not supported for ACL destinations")
	ErrAutogroupDangerAllDst       = errors.New("cannot use autogroup:danger-all as a dst")
	ErrAutogroupNotSupportedSSHSrc = errors.New("autogroup not supported for SSH sources")
	ErrAutogroupNotSupportedSSHDst = errors.New("autogroup not supported for SSH destinations")
	ErrHostNotDefined              = errors.New("host not defined in policy")
	ErrSSHSourceAliasNotSupported  = errors.New("alias not supported for SSH source")
	ErrSSHDestAliasNotSupported    = errors.New("alias not supported for SSH destination")
	ErrUnknownField                = errors.New("unknown field")
	ErrProtocolNoSpecificPorts     = errors.New("protocol does not support specific ports")
	ErrTestEmptyAssertions         = errors.New("test entry must have at least one of \"accept\" or \"deny\"")
	ErrTestProtocolNotAllowed      = errors.New("test protocol must be tcp, udp, sctp, or empty")
	ErrTestDestinationMultiPort    = errors.New("test destination port must be a single port")
	ErrTestDestinationCIDR         = errors.New("test destination must be a single host, not a CIDR range")
	ErrAutogroupInternetTestDst    = errors.New("autogroup:internet not valid as a test destination")
	ErrSSHTestEmptySrc             = errors.New("SSH tests entry must have a non-empty src")
	ErrSSHTestEmptyDst             = errors.New("SSH tests entry must have at least one dst")
	ErrSSHTestDstUnknownTag        = errors.New("SSH tests dst contains unknown tag")
	ErrSSHTestDstDisallowedElement = errors.New("SSH tests dst contains disallowed element")
)

type resolved struct {
	ips netipx.IPSet
}

func newResolved(ipb *netipx.IPSetBuilder) (resolved, error) {
	ips, err := ipb.IPSet()
	if err != nil {
		return resolved{}, err
	}

	return resolved{ips: *ips}, nil
}

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Remove the autogroup:internet entry from the tests block
  2. Verify internet/exit-node access with a real client or integration test instead
  3. If you want a packet-filter-level assertion, test against a concrete exit-node host address

Example fix

// before
"tests": [{"src": "user1", "accept": ["autogroup:internet:443"]}]
// after
"tests": [{"src": "user1", "accept": ["100.100.100.1:443"]}]  // or drop the test
Defensive patterns

Strategy: validation

Validate before calling

func isAutogroupInternet(dst string) bool { return dst == "autogroup:internet" || strings.HasPrefix(dst, "autogroup:internet:") }
// reject such dst strings when building tests entries

Try / catch

if errors.Is(err, policyv2.ErrAutogroupInternetTestDst) {
    // remove the autogroup:internet test; verify internet access outside the tests block
}

Prevention

When it happens

Trigger: A tests entry like {"src": "user1", "accept": ["autogroup:internet:443"]}. Raised when the parsed destination alias is *AutoGroup == AutoGroupInternet.

Common situations: Adding a regression test for 'can this user reach the internet via an exit node'; copying an existing grant that uses autogroup:internet as dst into the tests block; misunderstanding that tests evaluate only the packet filter.

Related errors


AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15). Data as JSON: /api/errors/4c303a8d932e141e. Report an issue: GitHub.