MHSanaei/3x-ui · error
address is required
Error message
address is required
What it means
NormalizeHost rejects an address that is empty after TrimSpace with 'address is required'. It is the first validation in the normalization pipeline (strip brackets → parse IP → validate hostname pattern), so it fires before any other host error. Any caller (e.g. Remote.baseURL in the node runtime) that feeds it an unset field hits this immediately.
Source
Thrown at internal/util/netsafe/netsafe.go:68
}
conn, derr := defaultDialer.DialContext(ctx, network, net.JoinHostPort(ipAddr.IP.String(), port))
if derr == nil {
return conn, nil
}
lastErr = derr
}
if lastErr == nil {
lastErr = fmt.Errorf("no usable address for %s", host)
}
return nil, lastErr
}
var hostnamePattern = 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 NormalizeHost(addr string) (string, error) {
addr = strings.TrimSpace(addr)
if addr == "" {
return "", fmt.Errorf("address is required")
}
if strings.HasPrefix(addr, "[") && strings.HasSuffix(addr, "]") {
addr = addr[1 : len(addr)-1]
}
if ip := net.ParseIP(addr); ip != nil {
return ip.String(), nil
}
if len(addr) > 253 || !hostnamePattern.MatchString(addr) {
return "", fmt.Errorf("invalid host %q", addr)
}
return addr, nil
}
View on GitHub (pinned to ad32144c42)
Solutions
- Set the address field on the offending record (node settings, subscription config) to a hostname or IP.
- If building an API client, include the address key in the create/update payload and validate client-side.
- Trim user input before saving so whitespace-only values are caught at entry.
- Find the caller from the stack trace to identify which record has the empty address.
Example fix
// before
addr := node.Address // "" -> address is required
host, err := netsafe.NormalizeHost(addr)
// after
addr := strings.TrimSpace(node.Address)
if addr == "" {
return fmt.Errorf("node %d has no address", node.Id)
}
host, err := netsafe.NormalizeHost(addr) Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(node.Address) == "" {
return fmt.Errorf("node address is required")
} Prevention
- Make address a required field in node forms and API payloads.
- Validate on save, not on first use in the runtime path.
- Add a DB check constraint or a startup audit for empty addresses.
When it happens
Trigger: Calling NormalizeHost(""), NormalizeHost(" "), or passing a struct field that was never populated — e.g. a node/sub-node record saved with an empty Address column, then used to build a base URL.
Common situations: A node added to the panel with the address left blank; a form/UI bug not marking address required; an API client POSTing a node JSON without the address key; whitespace-only value pasted from clipboard.
Related errors
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/c398bca7290d673e.
Report an issue: GitHub.