DEV Community

Vix
Vix

Posted on

Why IP geolocation fails — and what to do about it

Why IP geolocation fails — and what to do about it

IP geolocation is one of those technologies that works well enough that people use it everywhere, and badly enough that it regularly causes real problems. If you've ever been locked out of a service because you were "in the wrong country," or seen a website serve you the wrong currency, or had a VPN break an app — you've experienced the failure modes firsthand.

This article explains why geolocation fails, when it fails most, and how to build software that handles those failures gracefully.


What IP geolocation actually does

Every IP address is assigned to an organization — an ISP, a company, a university, a cloud provider. That assignment is public record, documented in databases maintained by regional internet registries (ARIN, RIPE, APNIC, LACNIC, AFRINIC). Geolocation databases map those organizational assignments to physical locations using a combination of:

  • Registry data (where the organization is headquartered)
  • BGP routing data (where traffic for that IP originates)
  • Active probing and latency measurements
  • Commercial data purchases from ISPs

The result is an educated guess, not a lookup. The databases are updated periodically — MaxMind, for example, updates GeoLite2 twice per week — but IP assignments change faster than updates can track, and the underlying mapping is inherently approximate.


The five most common failure modes

1. VPNs and proxies

When a user connects through a VPN, the IP address you see is the VPN exit node — which might be in a completely different country from the user. This is by design from the user's perspective, but it means your geolocation data is wrong for that session.

VPN usage has grown substantially. Estimates vary, but surveys consistently show 25-30% of internet users use a VPN at least monthly. In some regions — particularly in countries with content restrictions — it's the majority of users.

What to do: if accurate location matters for your application, don't rely on IP alone. Use geolocation as a default, but let users override it. Never silently use IP geolocation for anything with legal or financial consequences.

2. Mobile carrier NAT

Mobile networks frequently use carrier-grade NAT (CGNAT), where thousands of users share a single public IP address. That shared IP may be located at a carrier data center in a different city or region from the actual users behind it.

A user in a rural area connecting through a mobile carrier might have their traffic exit at a major city hub, making them appear to be in that city.

What to do: for mobile users, IP geolocation accuracy drops significantly at the city level. Treat city-level data from mobile IPs as approximate at best.

3. Corporate networks and offices

Companies often route all employee internet traffic through a central gateway, sometimes in a different country from where the employee is actually working. Remote workers, in particular, frequently appear to be in the location of their company's headquarters or VPN server.

What to do: be especially cautious about IP geolocation for B2B applications where users are likely to be on corporate networks.

4. Cloud and datacenter IPs

Traffic originating from cloud providers (AWS, Google Cloud, Azure, Oracle) doesn't represent a user's location — it represents a data center location. If your application is being accessed by another application running in the cloud, the geolocation will reflect where that server is, not where the actual user or operator is.

import requests

def get_ip_info():
    r = requests.get('https://ippubblico.org/?api=1')
    data = r.json()
    return {
        'ip':  data['ip'],
        'isp': data['isp'],
        'asn': data['asn'],
    }

# Check if traffic is from a cloud provider
CLOUD_ASNS = {
    'AS16509',  # Amazon AWS
    'AS15169',  # Google Cloud
    'AS8075',   # Microsoft Azure
    'AS396982', # Google Cloud (secondary)
    'AS14061',  # DigitalOcean
    'AS20473',  # Vultr
}

info = get_ip_info()
is_cloud = info['asn'] in CLOUD_ASNS
Enter fullscreen mode Exit fullscreen mode

What to do: check the ASN of incoming connections. If it belongs to a known cloud provider, treat the geolocation as unreliable and either skip geolocation-based logic or flag the request for additional verification.

5. Stale database entries

IP blocks get reassigned. A block that belonged to an ISP in Germany might be sold and reassigned to a company in Brazil. Database providers update their data, but there's always a lag — and during that lag, every request from those IPs returns wrong data.

This is particularly common with IPv6, where the geolocation databases are less complete and less frequently updated than IPv4.

What to do: for IPv6 addresses, treat geolocation data as less reliable than for IPv4. Design your application to degrade gracefully when geolocation data is missing or uncertain.


How to check what geolocation actually returns

Before building on top of geolocation data, test what your users actually see. IPPubblico.org returns the full geolocation data for the requesting IP with no setup:

curl "https://ippubblico.org/?api=1"
Enter fullscreen mode Exit fullscreen mode
{
  "status": "ok",
  "ip": "203.0.113.42",
  "isp": "NTT Communications",
  "asn": "AS2914",
  "geo": {
    "city": "Tokyo",
    "region": "Tokyo",
    "country": "Japan",
    "country_code": "JP",
    "lat": 35.6893,
    "lon": 139.6899
  }
}
Enter fullscreen mode Exit fullscreen mode

The asn and isp fields are particularly useful for detecting the failure modes above — a VPN, cloud provider, or CGNAT carrier shows up clearly in those fields even when the country/city data looks plausible.


Accuracy by use case

Use case Accuracy Notes
Country detection ~95% Good for most users, breaks for VPN/corporate
Region/state ~75% Acceptable for content personalization
City ~50-60% Rough approximation, unreliable for mobile
Coordinates Variable Treat as center of city/region, not actual location
Street address Not possible Never attempt this with IP geolocation

These numbers are rough industry estimates — real accuracy depends heavily on your user base. A B2C consumer app will see higher accuracy than a B2B tool used by people on corporate networks.


Building geolocation-aware code that handles failures

Always provide a fallback

async function getUserCountry() {
  try {
    const res  = await fetch('https://ippubblico.org/?api=1', {
      signal: AbortSignal.timeout(3000)
    });
    const data = await res.json();
    return data.geo?.country_code ?? 'US'; // fallback to US
  } catch {
    return 'US'; // fallback on network error
  }
}
Enter fullscreen mode Exit fullscreen mode

Let users override

function getEffectiveCountry(detectedCountry) {
  // Check if user has manually set their country
  const userOverride = localStorage.getItem('user_country');
  return userOverride ?? detectedCountry;
}
Enter fullscreen mode Exit fullscreen mode

Use geolocation for defaults, not enforcement

// Good: use geolocation to pre-select a currency, but let users change it
const detectedCountry = await getUserCountry();
const defaultCurrency = CURRENCY_MAP[detectedCountry] ?? 'USD';

// Bad: block users based on geolocation alone
if (detectedCountry === 'XX') {
  throw new Error('Service not available in your country'); // Don't do this
}
Enter fullscreen mode Exit fullscreen mode

Check ASN for cloud/VPN detection

import requests

def get_connection_type(ip=None):
    url = 'https://ippubblico.org/?api=1'
    if ip:
        url += f'&ip={ip}'

    data = requests.get(url, timeout=5).json()
    asn = data.get('asn', '')
    isp = data.get('isp', '').lower()

    # Known cloud/VPN indicators
    cloud_keywords = ['amazon', 'google', 'microsoft', 'digitalocean',
                      'vultr', 'linode', 'ovh', 'hetzner']
    vpn_keywords   = ['vpn', 'proxy', 'tunnel', 'nordvpn', 'expressvpn']

    is_cloud = any(kw in isp for kw in cloud_keywords)
    is_vpn   = any(kw in isp for kw in vpn_keywords)

    return {
        'country':   data['geo']['country_code'],
        'is_cloud':  is_cloud,
        'is_vpn':    is_vpn,
        'reliable':  not is_cloud and not is_vpn,
    }
Enter fullscreen mode Exit fullscreen mode

What geolocation is good for

Despite the failure modes, IP geolocation is genuinely useful when used appropriately:

  • Default language/locale selection — reasonable default, easy to override
  • Content delivery optimization — CDN routing, selecting the nearest server
  • Fraud detection signals — one signal among many, not a definitive check
  • Analytics and traffic analysis — aggregate country-level data is reliable even if individual lookups sometimes aren't
  • Regulatory compliance logging — logging the detected country for audit purposes, while accepting that it may be wrong

What geolocation should never be used for alone

  • Access control or blocking — VPNs and CGNAT mean the "wrong" people will always get through, and the "right" people will sometimes get blocked
  • Legal jurisdiction determination — use user-provided and verified information instead
  • Payment fraud prevention — a signal, not a decision
  • Anything with permanent consequences — detected location can change on the next request

Conclusion

IP geolocation is a useful heuristic, not a reliable fact. The failure modes — VPNs, CGNAT, corporate gateways, cloud IPs, stale data — are common enough that any production system should be designed with them in mind from the start.

The practical rule: use geolocation for defaults and personalization, never for enforcement. Let users override it. Check ASN data to flag likely-unreliable cases. And test what your actual users see before making architectural decisions based on geolocation accuracy assumptions.


Have you run into a particularly bad geolocation failure in production? The comments are a good place to share war stories.

Top comments (0)