juanfont/headscale · error
auto approver is not an alias
Error message
auto approver is not an alias
What it means
Returned by resolveAutoApprovers (hscontrol/policy/v2/types.go:1541,1556) when an entry in the policy's autoApprovers routes/exitNode lists is not an Alias implementation. Both sites are marked "Should never happen" — the JSON unmarshalling path only ever produces Alias values, so this is an internal invariant check, not a user-facing validation.
Source
Thrown at hscontrol/policy/v2/types.go:128
ErrMultipleUsersFound = errors.New("multiple users found")
ErrInvalidGroupFormat = errors.New("group must start with 'group:'")
ErrInvalidTagFormat = errors.New("tag must start with 'tag:'")
ErrInvalidHostname = errors.New("invalid hostname")
ErrHostResolve = errors.New("error resolving host")
ErrInvalidPrefix = errors.New("invalid prefix")
ErrInvalidAutogroup = errors.New("invalid autogroup")
ErrUnknownAutogroup = errors.New("unknown autogroup")
ErrHostportMissingColon = errors.New("hostport must contain a colon")
ErrTypeNotSupported = errors.New("type not supported")
ErrInvalidAlias = errors.New("invalid alias format")
ErrInvalidAutoApprover = errors.New("invalid auto approver format")
ErrInvalidOwner = errors.New("invalid owner format")
ErrGroupNotDefined = errors.New("group not defined in policy")
ErrInvalidGroupMember = errors.New("invalid group member type")
ErrGroupValueNotArray = errors.New("group value must be an array of users")
ErrInvalidHostIP = errors.New("hostname contains invalid IP address")
ErrTagNotDefined = errors.New("tag not found")
ErrAutoApproverNotAlias = errors.New("auto approver is not an alias")
ErrInvalidACLAction = errors.New("invalid ACL action")
ErrInvalidSSHAction = errors.New("invalid SSH action")
ErrInvalidProtocolNumber = errors.New("invalid protocol number")
ErrProtocolLeadingZero = errors.New("leading 0 not permitted in protocol number")
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")View on GitHub (pinned to 565fd254d0)
Solutions
- If you hit this as a headscale user, report it as a bug — the policy file cannot cause it
- If you are extending policy v2 in Go, ensure every element you place in AutoApprovers.Routes[prefix] or AutoApprovers.ExitNode implements the Alias interface
Defensive patterns
Strategy: try-catch
Type guard
func isAutoApproverNotAlias(err error) bool {
return errors.Is(err, policy.ErrAutoApproverNotAlias)
} Try / catch
ips, exit, err := resolveAutoApprovers(p, users, nodes)
if err != nil {
if errors.Is(err, policy.ErrAutoApproverNotAlias) {
// internal invariant breach — do not retry, report upstream
log.Error().Err(err).Msg("autoApprover invariant violated; please report")
}
return err
} Prevention
- Treat this error as a bug report, not a config problem
- If you construct Policy programmatically, unit-test that autoApprovers entries satisfy the Alias interface
When it happens
Trigger: Not reachable through normal policy files. Can only fire if Go code programmatically constructs a Policy with AutoApprovers containing a non-Alias value (e.g. after an API change or a faulty refactor of the Alias interface set).
Common situations: Essentially never seen by config authors. Would appear in headscale logs at policy-compile time if a future code change violated the invariant, e.g. adding a new autoApprover kind without implementing Alias.
Related errors
- tag owner is not an Alias
- must be a positive duration
- checkPeriod is only valid with action "check"
- invalid localpart format, must be localpart:*@<domain>
- users must be specified
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/8185a66f944b9d95.
Report an issue: GitHub.