juanfont/headscale · error

error resolving host

Error message

error resolving host

What it means

Host.resolve (hscontrol/policy/v2/types.go:621-630) looks the hostname up in the policy's own hosts map (p.Hosts) — headscale does NOT do DNS resolution for ACL aliases. If the name has no entry, this sentinel wrapped with the name is returned and policy compilation fails.

Source

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

// 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 @")
	ErrUserNotFound                = errors.New("user not found")
	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")

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Add the host to the policy's hosts map with its IP/CIDR
  2. Or replace the hostname token with the literal IP prefix in the ACL
  3. Keep hosts keys and ACL references in sync — grep the policy for the name

Example fix

// before
{"acls": [{"action": "accept", "src": ["group:admins"], "dst": ["example-host:443"]}]}
// after
{"hosts": {"example-host": "10.0.0.5/32"}, "acls": [{"action": "accept", "src": ["group:admins"], "dst": ["example-host:443"]}]}
Defensive patterns

Strategy: validation

Validate before calling

// every host referenced in rules must exist in hosts map
for _, name := range referencedHosts(policy) {
    if _, ok := policy.Hosts[name]; !ok {
        return fmt.Errorf("host %q not defined in hosts map", name)
    }
}

Type guard

func hostDefined(hosts map[string]string, name string) bool { _, ok := hosts[name]; return ok }

Try / catch

if errors.Is(err, policy.ErrHostResolve) {
    // add a hosts entry or replace with literal IP prefix
}

Prevention

When it happens

Trigger: An ACL references 'example-host:443' but the policy has no {"hosts": {"example-host": "10.0.0.5/32"}} entry. Triggered at compile time via Host.Resolve, e.g. during 'headscale policy set' or server reload with the policy active.

Common situations: Assuming headscale resolves public DNS names in ACLs (Tailscale SaaS-style behaviour); hosts entry renamed or removed while ACLs still reference it; typo between hosts key and ACL reference.

Related errors


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