juanfont/headscale · warning · util.ErrUsernameTooShort
username must be at least 2 characters long
Error message
username must be at least 2 characters long
What it means
ErrUsernameTooShort (hscontrol/util/dns.go:30) is returned by ValidateUsername when the username is shorter than 2 characters. Usernames become MagicDNS labels / identity names, and single- or zero-character names are rejected because they cannot form a valid identity label. It is the first check in ValidateUsername (length, then first-letter, then '@' count, then charset).
Source
Thrown at hscontrol/util/dns.go:30
"go4.org/netipx"
"tailscale.com/util/dnsname"
)
const (
ByteSize = 8
ipv4AddressLength = 32
ipv6AddressLength = 128
// LabelHostnameLength is the maximum length for a DNS label,
// value related to RFC 1123 and 952.
LabelHostnameLength = 63
)
// DNS validation errors. Hostname-side validation lives on
// `tailscale.com/util/dnsname` and [state.NodeStore] collision handling; only
// the username-side errors stay in this package.
var (
ErrUsernameTooShort = errors.New("username must be at least 2 characters long")
ErrUsernameMustStartLetter = errors.New("username must start with a letter")
ErrUsernameTooManyAt = errors.New("username cannot contain more than one '@'")
ErrUsernameInvalidChar = errors.New("username contains invalid character")
)
// ValidateUsername checks if a username is valid.
// It must be at least 2 characters long, start with a letter, and contain
// only letters, numbers, hyphens, dots, and underscores.
// It cannot contain more than one '@'.
// It cannot contain invalid characters.
func ValidateUsername(username string) error {
// Ensure the username meets the minimum length requirement
if len(username) < 2 {
return ErrUsernameTooShort
}
// Ensure the username starts with a letter
if !unicode.IsLetter(rune(username[0])) {View on GitHub (pinned to 565fd254d0)
Solutions
- Use a username of at least 2 characters
- If the name comes from OIDC, map a different claim or normalize it before it reaches user creation
- Pre-check with util.ValidateUsername in your own tooling before calling the API
Example fix
# before headscale users create a # after headscale users create alice
Defensive patterns
Strategy: validation
Validate before calling
if len(username) < 2 {
return fmt.Errorf("username %q too short: %w", username, util.ErrUsernameTooShort)
}
if err := util.ValidateUsername(username); err != nil { // full check
return err
} Try / catch
if err := util.ValidateUsername(name); err != nil {
if errors.Is(err, util.ErrUsernameTooShort) {
name = defaultPrefix + name // pad to >= 2 chars per your convention
} else {
return err
}
} Prevention
- Enforce >=2 chars in provisioning forms before hitting the API
- For OIDC, validate the mapped claim before first login creates a user
When it happens
Trigger: Calling util.ValidateUsername with a 0- or 1-character string; reached from user-creation paths (CLI `headscale users create x`, OIDC login mapping a provider sub/email to a name, API user creation).
Common situations: Creating a test user with a one-letter name; an OIDC provider returning an unusual claim (e.g. single-char preferred_username); scripted provisioning that derived an empty username from an email local-part.
Related errors
- username must start with a letter
- username cannot contain more than one '@'
- username contains invalid character: '%c'
- is not valid
- username must contain @
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/47456c1887c0aa80.
Report an issue: GitHub.