Billionmail/BillionMail · error

local IP not found

Error message

local IP not found

What it means

GetLocalIP in core/internal/service/public/common.go tries to determine the machine's local (private) IP address by dialing/inspecting interfaces. If no candidate local IP can be determined, it returns the sentinel error "local IP not found". Callers use this to identify which address the host would use for outbound traffic.

Source

Thrown at core/internal/service/public/common.go:2202

			defer dk.Close()
			// If the local IP starts with 172., it may be a Docker container, so we try to get the host's IP
			res, err := dk.ExecHostShellCommand(context.Background(), "ip addr | grep -E -o '[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}' | grep -E -v \"^127\\.|^255\\.|^0\\.\" | head -n 1")

			if err == nil && res != nil {
				res.Output = SanitizeIPChars(res.Output)

				if IsIpAddr(res.Output) {
					localIp = res.Output
				}
			}
		}
	}

	if localIp != "" {
		return localIp, nil
	}

	return "", errors.New("local IP not found")
}

// GetServerIPAndLocalIP retrieves the server's public and local IP addresses.
func GetServerIPAndLocalIP() (string, string, error) {
	publicIP, err := GetServerIP()
	if err != nil {
		return "", "", err
	}

	localIP, err := GetLocalIP()
	if err != nil {
		return "", "", err
	}

	return publicIP, localIP, nil
}

// Get server port

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Bring up a network interface and assign it an address (docker network config, ifup, ip addr add).
  2. For containers, ensure the container joins a user-defined bridge network with an assigned IP.
  3. Fall back to a configurable override (env var or config) for the local IP when auto-detection is impossible.
  4. Retry after network initialization if this runs during startup before interfaces are ready.

Example fix

// before
localIP, err := public.GetLocalIP() // "local IP not found" in bare container
// after
localIP := os.Getenv("LOCAL_IP")
if localIP == "" {
    localIP, err = public.GetLocalIP()
    if err != nil {
        log.Printf("auto-detect failed, defaulting to 127.0.0.1: %v", err)
        localIP = "127.0.0.1"
    }
}
Defensive patterns

Strategy: fallback

Validate before calling

ifaces, _ := net.Interfaces()
hasIPv4 := false
for _, i := range ifaces {
    if i.Flags&net.FlagUp != 0 && i.Flags&net.FlagLoopback == 0 {
        addrs, _ := i.Addrs()
        if len(addrs) > 0 { hasIPv4 = true }
    }
}
if !hasIPv4 { log.Println("warning: no non-loopback interface with an address") }

Try / catch

localIP, err := public.GetLocalIP()
if err != nil {
    if fallback := os.Getenv("LOCAL_IP"); fallback != "" {
        localIP = fallback
    } else {
        localIP = "127.0.0.1"
        log.Printf("local IP detection failed, using loopback: %v", err)
    }
}

Prevention

When it happens

Trigger: Calling GetLocalIP() on a machine with no usable non-loopback network interfaces, in a container/netns with only the loopback interface up, or when interfaces exist but have no IPv4 address bound to them.

Common situations: Running in a minimal Docker container without networking configured yet, boot-time code executing before interfaces are up, VMs with networking disabled, or test environments with no network.

Related errors


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/870f059c74a2fd2e. Report an issue: GitHub.