Billionmail/BillionMail · error
Failed to get server IP: %v
Error message
Failed to get server IP: %v
What it means
GetSPFRecord fails when public.GetServerIP() cannot determine the server's public IP, which is required to build the SPF record's ip4/ip6 mechanism. The underlying error (network failure, IP-lookup service down, missing outbound connectivity) is wrapped verbatim.
Source
Thrown at core/internal/service/domains/domains.go:720
Type: "TXT",
Host: "_dmarc",
Value: fmt.Sprintf("v=DMARC1;p=quarantine;rua=mailto:admin@%s", domain),
}
if validateImmediate {
// Validate the DMARC record
record.Valid = ValidateTXTRecord(record, domain)
}
return
}
// GetSPFRecord retrieves the SPF record for a given domain.
func GetSPFRecord(domain string, validateImmediate bool) (record v1.DNSRecord, err error) {
serverIP, err := public.GetServerIP()
if err != nil {
err = fmt.Errorf("Failed to get server IP: %v", err)
return
}
ipType := "ip4"
if strings.Contains(serverIP, ":") {
ipType = "ip6"
}
// Format SPF record
record = v1.DNSRecord{
Type: "TXT",
Host: "@",
Value: fmt.Sprintf("v=spf1 +a +mx +%s:%s -all", ipType, serverIP),
}
if validateImmediate {
// Validate the SPF recordView on GitHub (pinned to fc36c76c05)
Solutions
- Verify outbound connectivity from the server (curl ifconfig.me) and fix firewall/proxy rules
- Set a static/explicit server IP in configuration if the environment supports it, bypassing auto-detection
- Retry once the IP service is available; consider caching the server IP to reduce dependency
- If behind NAT, ensure the detected IP matches the public MX IP or override it manually
Example fix
// before: hard dependency on live IP lookup
serverIP, err := public.GetServerIP()
// after: fall back to configured IP
ip := os.Getenv("SERVER_PUBLIC_IP")
if ip == "" {
ip, err = public.GetServerIP()
} Defensive patterns
Strategy: fallback
Validate before calling
if ip := os.Getenv("SERVER_PUBLIC_IP"); ip != "" { return nil } // configured override, skip lookup
if err := net.DialTimeout("tcp", "1.1.1.1:53", 3*time.Second); err != nil { return fmt.Errorf("no outbound network for IP detection") } Try / catch
serverIP, err := public.GetServerIP()
if err != nil {
log.Printf("IP detection failed: %v — using configured override or retrying", err)
serverIP = cfg.PublicIP
if serverIP == "" { return err }
} Prevention
- Configure a static public IP override for servers behind NAT or in restricted networks
- Cache the detected server IP to reduce dependence on external IP-echo services
- Monitor outbound connectivity from the mail server
When it happens
Trigger: public.GetServerIP() errors — no outbound internet access, the external IP-echo service unreachable or rate-limited, DNS resolution failure, or the host has no default route (common in air-gapped/CI environments).
Common situations: Running in an offline/CI container, firewall blocking outbound HTTP(S) used for IP discovery, IPv6-only or NAT'd environments confusing the lookup, or the IP-detection service being temporarily down.
Related errors
- No SPF record found (from cache)
- No SPF record found
- resolve failed
- cartesia clone API call: %w
- base URL not configured
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/5f9698443697ba4b.
Report an issue: GitHub.