CloakHQ/CloakBrowser · error · InvalidOperationException

GeoIP lookup failed for

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.

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.

Appendix: 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)