juanfont/headscale · error · ErrInvalidLocalpart
%w: empty domain in %q
Error message
%w: empty domain in %q
What it means
Error "%w: empty domain in %q" thrown in juanfont/headscale.
Source
Thrown at hscontrol/policy/v2/types.go:3092
}
pattern := strings.TrimPrefix(string(u), SSHUserLocalpartPrefix)
// Must be *@<domain>
atIdx := strings.LastIndex(pattern, "@")
if atIdx < 0 {
return "", fmt.Errorf("%w: missing @ in %q", ErrInvalidLocalpart, u)
}
localPart := pattern[:atIdx]
domain := pattern[atIdx+1:]
if localPart != "*" {
return "", fmt.Errorf("%w: local part must be *, got %q in %q", ErrInvalidLocalpart, localPart, u)
}
if domain == "" {
return "", fmt.Errorf("%w: empty domain in %q", ErrInvalidLocalpart, u)
}
return domain, nil
}
// MarshalJSON marshals the [SSHUser] to JSON.
func (u SSHUser) MarshalJSON() ([]byte, error) {
return json.Marshal(string(u))
}
// UnmarshalJSON trims surrounding whitespace per element. A whitespace-
// only entry collapses to `""` and surfaces as `user "" is not valid` in
// the per-rule [Policy.validate] pass.
func (u *SSHUser) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil { //nolint:noinlineerr
return err
}View on GitHub (pinned to 565fd254d0)
Solutions
- Inspect the wrapped error for the underlying cause and correct the failing condition (); retry the operation after fixing the input, configuration, or environment.
Example fix
Inspect the wrapped error for the underlying cause and correct the failing condition (); retry the operation after fixing the input, configuration, or environment.
When it happens
Trigger: Thrown at hscontrol/policy/v2/types.go:3092 when the library encounters an invalid state.
Common situations: A localpart entry has an empty domain after '@'. Provide a valid domain, e.g. *@example.com.
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/c371151df1730ac2.
Report an issue: GitHub.