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
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"
{
"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
}
}
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
}
}
Let users override
function getEffectiveCountry(detectedCountry) {
// Check if user has manually set their country
const userOverride = localStorage.getItem('user_country');
return userOverride ?? detectedCountry;
}
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
}
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,
}
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)