juanfont/headscale · error

%w: %q

Error message

%w: %q

What it means

Host.Validate rejected a hostname alias because it does not satisfy the hostname grammar checked by isHost() — typically characters outside the allowed set, a missing label, leading/trailing dots, or a value that is actually another alias form.

Source

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

func (t *Tag) String() string {
	return string(*t)
}

// MarshalJSON marshals the Tag to JSON.
func (t *Tag) MarshalJSON() ([]byte, error) {
	return json.Marshal(string(*t))
}

// Host is a string that represents a hostname.
type Host string

func (h *Host) Validate() error {
	if isHost(string(*h)) {
		return nil
	}

	return fmt.Errorf("%w: %q", ErrInvalidHostname, *h)
}

func (h *Host) UnmarshalJSON(b []byte) error {
	*h = Host(strings.Trim(string(b), `"`))

	err := h.Validate()
	if err != nil {
		return err
	}

	return nil
}

func (h *Host) Resolve(p *Policy, _ types.Users, nodes views.Slice[types.NodeView]) (ResolvedAddresses, error) {
	return newResolvedAddresses(h.resolve(p, nil, nodes))
}

func (h *Host) resolve(p *Policy, _ types.Users, _ views.Slice[types.NodeView]) (*netipx.IPSet, error) {

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Use a DNS-style name: lowercase letters, digits, hyphens, and dots, each label non-empty, e.g. 'web.example.com'.
  2. Remove spaces, underscores, and stray punctuation.
  3. If the value is meant to be a different alias type, use the right type (user email, tag:, group:).

Example fix

// before
"hosts": {"web server": "100.64.0.10/32"}

// after
"hosts": {"web-server": "100.64.0.10/32"}
Defensive patterns

Strategy: validation

Validate before calling

var hostRe = regexp.MustCompile(`^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$`)
func validHostname(s string) bool { return hostRe.MatchString(s) && len(s) <= 253 }

Try / catch

if err := host.Validate(); err != nil {
    if errors.Is(err, v2.ErrInvalidHostname) {
        // strip spaces/underscores; use DNS-style label
    }
    return err
}

Prevention

When it happens

Trigger: Hosts-map or destination values like 'web server' (space), '.web', 'web..example', or 'user@host' assigned to a Host field. isHost(string(h)) returns false in Host.Validate.

Common situations: Hand-editing the hosts section with display names containing spaces or underscores; pasting FQDNs with trailing dots; using an email or tag where a hostname was expected.

Related errors


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