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

  1. Use a plain IPv6 literal, e.g. "2001:db8::1".
  2. If the target only has IPv4, create an "A" record instead of AAAA.
  3. 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

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


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/c34b5e577fdcbcf8. Report an issue: GitHub.