CloakHQ/CloakBrowser · error · InvalidOperationException

GeoIP resolution failed: GeoIP database is unavailable

Error message

GeoIP resolution failed: GeoIP database is unavailable

What it means

An egress IP was discovered, but the resolver could not locate a MaxMind GeoIP database file on disk (dbPath == null), so the city/timezone lookup cannot run. The library ships or downloads this database lazily, and this error means that acquisition/lookup failed. It is an environment/setup problem, not a network-egress one.

Source

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

        // Exit IP (through proxy, or the machine's own public IP when proxyUrl is
        // null/empty) is most accurate - gateway DNS may differ from exit. Resolved
        // even when the DB is unavailable: the IP does not need the DB, and dropping
        // it on a DB hiccup would let WebRTC fall back to the real IP behind a proxy
        // while the connection shows the proxy IP - a real deanonymization.
        var ip = await ResolveExitIpAsync(proxyUrl, RemainingSeconds(deadline), ct).ConfigureAwait(false);
        // Hostname fallback only applies to a proxy; no proxy -> echo services only.
        if (ip == null && !string.IsNullOrEmpty(proxyUrl) && !DeadlineExpired(deadline))
            ip = ResolveProxyIp(proxyUrl);
        if (ip == null || DeadlineExpired(deadline))
        {
            if (deadline != null && DeadlineExpired(deadline))
                throw new InvalidOperationException($"GeoIP resolution timed out after {timeout:0.0}s");
            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);
        }
    }

    // -----------------------------------------------------------------------

View on GitHub (pinned to d6bad5de26)

Solutions

  1. Ensure outbound access to the GeoIP database source on first run so it can download, then retry.
  2. Check the cache/data directory for the .mmdb file and restore or re-download it manually.
  3. Verify the library's data-directory configuration points to a writable, persistent location.
  4. If GeoIP data is not needed, use the code path that skips GeoIP resolution.

Example fix

// before
var geo = await browser.GeoIp.ResolveProxyGeoAsync(proxyUrl); // throws: db unavailable

// after
if (GeoIp.IsDatabaseAvailable())
    var geo = await browser.GeoIp.ResolveProxyGeoAsync(proxyUrl);
else
    await GeoIp.EnsureDatabaseAsync(ct); // fetch/reinstall the MaxMind db first
Defensive patterns

Strategy: validation

Validate before calling

if (!GeoIp.IsDatabaseAvailable())
    await GeoIp.EnsureDatabaseAsync(ct); // download/repair the .mmdb before resolving

Try / catch

catch (InvalidOperationException ex) when (ex.Message.Contains("GeoIP database is unavailable"))
{
    await GeoIp.EnsureDatabaseAsync(default);
    geo = await browser.GeoIp.ResolveProxyGeoAsync(proxyUrl); // retry once
}

Prevention

When it happens

Trigger: Calling ResolveProxyGeoAsync / MaybeResolveGeoIpAsync / Collect after egress IP discovery succeeded, when the GeoIP database path lookup returned null — database never downloaded, deleted from the cache directory, moved, or failed to initialize.

Common situations: First run in an offline environment where the MaxMind DB download failed silently; antivirus or cleanup tools deleting the .mmdb cache file; container images built without the GeoIP database; a broken or relocated cache directory after an upgrade.

Related errors


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