netbirdio/netbird · error
A record must be a valid IPv4 address
Error message
A record must be a valid IPv4 address
What it means
validateIPv4 parses Content with net.ParseIP and requires the result to have a 4-byte form (ip.To4() != nil). It fails for non-IP strings, malformed IPv4 ("192.0.2.256", "192.0.2"), and IPv6 literals (To4() is nil). Note the corollary: a v4-mapped IPv6 literal like "::ffff:192.0.2.1" is accepted because its To4() is non-nil.
Source
Thrown at management/internals/modules/zones/records/record.go:115
func (r *Record) EventMeta(zoneID, zoneName string) map[string]any {
return map[string]any{
"name": r.Name,
"type": string(r.Type),
"content": r.Content,
"ttl": r.TTL,
"zone_id": zoneID,
"zone_name": zoneName,
}
}
func validateIPv4(content string) error {
if content == "" {
return errors.New("A record is required") //nolint:staticcheck
}
ip := net.ParseIP(content)
if ip == nil || ip.To4() == nil {
return errors.New("A record must be a valid IPv4 address") //nolint:staticcheck
}
return nil
}
func validateIPv6(content string) error {
if content == "" {
return errors.New("AAAA record is required")
}
ip := net.ParseIP(content)
if ip == nil || ip.To4() != nil {
return errors.New("AAAA record must be a valid IPv6 address")
}
return nil
}
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Use a dotted-quad IPv4 literal, e.g. "192.0.2.1".
- If the target is IPv6, change the record type to "AAAA" instead.
- Trim whitespace and reject hostnames client-side before submission.
Example fix
// before
{"name": "api", "type": "A", "content": "2001:db8::1"}
// after
{"name": "api", "type": "AAAA", "content": "2001:db8::1"} Defensive patterns
Strategy: validation
Validate before calling
if api.DNSRecordType(req.Type) == api.DNSRecordTypeA {
if ip := net.ParseIP(req.Content); ip == nil || ip.To4() == nil {
return fmt.Errorf("content %q is not an IPv4 address", req.Content)
}
} Type guard
func isIPv4Literal(s string) bool {
ip := net.ParseIP(strings.TrimSpace(s))
return ip != nil && ip.To4() != nil
} Try / catch
if err := rec.Validate(); err != nil {
return respondBadRequest(err)
} Prevention
- Parse and validate the address client-side with the same ParseIP/To4 rule.
- Trim whitespace from pasted addresses; suggest switching to AAAA when the input parses as IPv6.
When it happens
Trigger: Type "A" with content "2001:db8::1", "example.com", "192.0.2", or " 192.0.2.1" (leading space).
Common situations: Pasting a hostname where an address is expected; using the A type for an IPv6 target; address strings copied with whitespace or units from a spreadsheet.
Related errors
- A record is required
- record name is required
- invalid record name format
- record type is required
- invalid CNAME target format
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/19a71818b4ea4a2b.
Report an issue: GitHub.