CloakHQ/CloakBrowser · error · InvalidOperationException

GeoIP lookup failed for {ip}: {exc.Message}

Error message

GeoIP lookup failed for {ip}: {exc.Message}

What it means

A MaxMind DatabaseReader was opened and the City lookup threw for the discovered IP; the library wraps that inner exception with the offending IP and message. Typical inner causes are address-not-found-in-database, a corrupted or truncated .mmdb file, or an invalid IP object. The original exception is preserved as InnerException.

Source

Thrown at dotnet/src/CloakBrowser/GeoIp.cs:138

            throw new InvalidOperationException("GeoIP resolution failed: could not discover the egress IP");
        }

        if (dbPath == null)
            throw new InvalidOperationException("GeoIP resolution failed: GeoIP database is unavailable");

        try
        {
            using var reader = new DatabaseReader(dbPath);
            var resp = reader.City(ip);
            var timezone = resp.Location?.TimeZone;
            var country = resp.Country?.IsoCode;
            string? locale = country != null && CountryLocaleMap.TryGetValue(country, out var l) ? l : null;
            CloakLog.Debug("GeoIP: {0} -> tz={1}, country={2}, locale={3}", ip, timezone, country, locale);
            return (timezone, locale, ip);
        }
        catch (Exception exc)
        {
            throw new InvalidOperationException($"GeoIP lookup failed for {ip}: {exc.Message}", exc);
        }
    }

    // -----------------------------------------------------------------------
    // Proxy IP resolution
    // -----------------------------------------------------------------------

    private static string? ResolveProxyIp(string proxyUrl)
    {
        try
        {
            if (!Uri.TryCreate(proxyUrl, UriKind.Absolute, out var uri))
                return null;
            var hostname = uri.Host;
            if (string.IsNullOrEmpty(hostname))
                return null;

            // Already a literal IP?

View on GitHub (pinned to d6bad5de26)

Solutions

  1. Inspect exc.InnerException to identify the exact MaxMind failure.
  2. If the egress IP is private/reserved, fix proxy configuration or skip GeoIP — public databases have no city data for it.
  3. Re-download or replace the GeoIP .mmdb database (corruption is the next most likely cause).
  4. Update the MaxMind database to a current build covering recent IPv6 allocations.

Example fix

// before
var (tz, locale, ip) = await browser.GeoIp.ResolveProxyGeoAsync(proxyUrl);

// after
catch (InvalidOperationException ex) when (ex.Message.StartsWith("GeoIP lookup failed"))
{
    _log.Warn(ex.InnerException, "GeoIP db lookup failed for {Ip}; falling back to default tz", ip);
    tz = "UTC"; // graceful fallback
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (IPAddress.IsPrivate(ip) || ip.IsIPv6LinkLocal)
    return GeoResult.Unknown; // MaxMind has no city data for private ranges

Try / catch

catch (InvalidOperationException ex) when (ex.Message.StartsWith("GeoIP lookup failed") && ex.InnerException != null)
{
    _log.Warn(ex.InnerException, "GeoIP db error for {Ip}; using default timezone", ip);
    tz = "UTC";
}

Prevention

When it happens

Trigger: Calling ResolveProxyGeoAsync / MaybeResolveGeoIpAsync / Collect with an egress IP that reader.City(ip) rejects — e.g. the IP is private/reserved (VPN/proxy on a LAN), the .mmdb file is corrupted, or the database lacks records for that address range.

Common situations: Proxies that surface private CGNAT ranges (100.64.x.x, 10.x.x.x) as the egress IP; partially downloaded or corrupted GeoLite2 database files; IPv6 addresses missing from an old database; concurrent readers hitting a database file being replaced.

Related errors


AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28). Data as JSON: /api/errors/f734cc95c569d6d6. Report an issue: GitHub.