netbirdio/netbird · error
AAAA record must be a valid IPv6 address
Error message
AAAA record must be a valid IPv6 address
What it means
validateIPv6 parses Content with net.ParseIP and rejects it when parsing fails or the result has a 4-byte form (ip.To4() != nil), i.e. when it is really IPv4. So an IPv4 literal like "192.0.2.1" under an AAAA record is rejected, as is a v4-mapped literal "::ffff:192.0.2.1" (its To4() is non-nil) and any malformed IPv6 string.
Source
Thrown at management/internals/modules/zones/records/record.go:126
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 plain IPv6 literal, e.g. "2001:db8::1".
- If the target only has IPv4, create an "A" record instead of AAAA.
- Do not use v4-mapped "::ffff:" notation; this validator deliberately treats it as IPv4 and rejects it.
Example fix
// before
{"name": "api", "type": "AAAA", "content": "192.0.2.1"}
// after
{"name": "api", "type": "A", "content": "192.0.2.1"} Defensive patterns
Strategy: validation
Validate before calling
if api.DNSRecordType(req.Type) == api.DNSRecordTypeAAAA {
if ip := net.ParseIP(req.Content); ip == nil || ip.To4() != nil {
return fmt.Errorf("content %q is not an IPv6 address", req.Content)
}
} Type guard
func isIPv6Literal(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
- Detect v4 input in the AAAA field and offer to create an A record instead.
- Avoid v4-mapped "::ffff:" literals; this validator rejects them.
When it happens
Trigger: Type "AAAA" with content "192.0.2.1", "::ffff:192.0.2.1", "2001:db8" (truncated), or a string that is not an IP at all.
Common situations: Pasting a v4 address into the AAAA field of a dual-stack form; assuming v4-mapped notation is an acceptable way to encode v4 targets in AAAA; zone files migrated with the wrong type column.
Related errors
- AAAA 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/c34b5e577fdcbcf8.
Report an issue: GitHub.