Error Medic

Google Maps API 403 Forbidden & Timeout Errors: Complete Troubleshooting Guide

Fix Google Maps API 403 errors fast: enable billing, whitelist your domain/IP, check API key restrictions, and resolve timeout issues in under 10 minutes.

Last updated:
Last verified:
1,791 words
Key Takeaways
  • A 403 Forbidden from the Maps API almost always means the API key is missing, restricted to wrong domains/IPs, or the associated GCP project has billing disabled or the Maps API not enabled.
  • Timeouts (OVER_QUERY_LIMIT or network-level) are caused by exceeding requests-per-second quotas, missing exponential back-off, or slow client-side rendering of large datasets.
  • Quick fix checklist: (1) verify billing is active in GCP Console, (2) confirm the Maps JavaScript/Geocoding/etc. API is enabled, (3) check HTTP referrer and IP restrictions on the key, (4) rotate or create a fresh key, (5) add retry logic with exponential back-off for timeouts.
Fix Approaches Compared
MethodWhen to UseTime to ApplyRisk
Enable billing on GCP projectMaps API was never billed or trial expired2 minLow — no code change
Add allowed HTTP referrerKey restricted and production domain not listed1 minLow — affects key security posture
Whitelist server IPServer-side API calls blocked by IP restriction2 minLow — may expose key if IP range is too broad
Create unrestricted key (dev only)Rapid local debugging only1 minHigh — never deploy to production
Enable specific Maps API serviceService (Geocoding, Places, etc.) not enabled in GCP2 minNone
Implement exponential back-offGetting OVER_QUERY_LIMIT or timeout errors at scale30 minLow — pure code addition
Increase quota via GCP ConsoleLegitimate traffic exceeds default QPS limits1 day (Google review)None

Understanding Google Maps API 403 and Timeout Errors

The Google Maps Platform returns HTTP 403 Forbidden when the request cannot be authorized. This is distinct from HTTP 401 (missing credentials) — 403 means credentials were presented but rejected. The JSON error body typically looks like:

{
  "error": {
    "code": 403,
    "message": "The caller does not have permission",
    "status": "PERMISSION_DENIED"
  }
}

For client-side Maps JavaScript API, the browser console shows:

Google Maps JavaScript API error: RefererNotAllowedMapError
Google Maps JavaScript API error: ApiNotActivatedMapError
Google Maps JavaScript API error: BillingNotEnabledMapError

Timeouts manifest differently: the HTTP response status is 200 but the JSON body contains "status": "OVER_QUERY_LIMIT", or the network request simply hangs until the browser or server timeout fires.


Step 1: Identify the Exact Error

Browser DevTools (Maps JavaScript API)

Open Chrome DevTools → Console. Google Maps injects descriptive error codes directly into the console. Copy the exact error code (e.g., RefererNotAllowedMapError) and cross-reference the Maps JavaScript API error codes reference.

Server-side / REST API calls

Capture the raw HTTP response:

curl -v "https://maps.googleapis.com/maps/api/geocode/json?address=New+York&key=YOUR_API_KEY" 2>&1 | grep -E '(HTTP|error|status|message)'

A 403 response will show:

< HTTP/2 403
{"error":{"code":403,"message":"API keys with referer restrictions cannot be used with this API.","status":"PERMISSION_DENIED"}}

Step 2: Check GCP Project Billing

This is the single most common cause of sudden 403 errors — the free trial expires or a billing account is detached.

  1. Open console.cloud.google.com and select your project.
  2. Navigate to Billing in the left sidebar.
  3. Confirm a billing account is linked and the account is active (not suspended).
  4. If billing is disabled, click Link a billing account and follow the prompts.

After re-enabling billing, Maps API calls typically resume within 5 minutes without any code changes.


Step 3: Verify the API Is Enabled

Each Maps Platform product (Maps JavaScript API, Geocoding API, Places API, Directions API, etc.) must be individually enabled.

  1. In GCP Console go to APIs & Services → Library.
  2. Search for the specific API you're calling (e.g., "Geocoding API").
  3. Click it — if the button says Enable, click it. If it says Manage, it's already enabled.

Alternatively via gcloud:

# List enabled APIs
gcloud services list --enabled --project=YOUR_PROJECT_ID | grep maps

# Enable Geocoding API
gcloud services enable geocoding-backend.googleapis.com --project=YOUR_PROJECT_ID

# Enable Maps JavaScript API
gcloud services enable maps-backend.googleapis.com --project=YOUR_PROJECT_ID

Step 4: Audit API Key Restrictions

Go to APIs & Services → Credentials and click your API key.

HTTP referrer restrictions (browser keys)

If you see restrictions like https://example.com/*, the key will 403 for:

  • http://example.com (wrong scheme)
  • https://www.example.com (www prefix not listed)
  • https://staging.example.com (subdomain not listed)
  • localhost:3000 (local dev not listed)

Add all needed patterns:

https://yourdomain.com/*
http://yourdomain.com/*
https://www.yourdomain.com/*
https://staging.yourdomain.com/*
http://localhost/*

IP address restrictions (server keys)

For server-side API calls, the outbound IP of your server must be listed. Find your server's IP:

curl -s https://api.ipify.org
# or on the server itself:
whoami && curl -s ifconfig.me

Add that IP (or CIDR range) to the key's IP restriction list in GCP Console.

API restriction mismatch

If the key has an API restriction (only allowed to call specific APIs) and you're calling an API not in that list, you get 403. Either add the API to the restriction list or use a key with no API restriction.


Step 5: Rotate the API Key (if compromised)

If your key was exposed in a public repository or logs, revoke it and create a new one:

# Using gcloud
gcloud alpha services api-keys delete KEY_ID --project=YOUR_PROJECT_ID

# Create new key
gcloud alpha services api-keys create \
  --display-name="Maps Production Key" \
  --allowed-referrers="https://yourdomain.com/*" \
  --api-target=service=maps-backend.googleapis.com \
  --project=YOUR_PROJECT_ID

Update the key in your app config/secrets manager and redeploy.


Step 6: Fix Timeout and OVER_QUERY_LIMIT Errors

The OVER_QUERY_LIMIT status means you've exceeded the requests-per-second (RPS) rate for your quota tier. The default is 50 QPS for most APIs on a paid account.

Check current quota usage:

# View quota metrics in GCP
gcloud monitoring metrics list --filter="metric.type=serviceruntime.googleapis.com/quota/rate/net_usage" 2>/dev/null
# Easier: GCP Console → APIs & Services → Quotas

Implement exponential back-off (Node.js example):

async function geocodeWithBackoff(address, maxRetries = 5) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const res = await fetch(
      `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&key=${process.env.GOOGLE_MAPS_API_KEY}`
    );
    const data = await res.json();

    if (data.status === 'OK') return data;
    if (data.status === 'OVER_QUERY_LIMIT') {
      const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;
      console.warn(`OVER_QUERY_LIMIT — retrying in ${delay}ms (attempt ${attempt + 1})`);
      await new Promise(r => setTimeout(r, delay));
      continue;
    }
    throw new Error(`Geocoding failed: ${data.status} — ${data.error_message || ''}`);
  }
  throw new Error('Max retries exceeded for geocoding request');
}

Request a quota increase:

If legitimate traffic exceeds defaults, go to APIs & Services → Quotas, select the quota line (e.g., "Geocoding API — Requests per day"), and click Edit Quotas to submit a quota increase request to Google.


Step 7: Validate the Fix End-to-End

# Test geocoding from the server that will make the call
curl -s "https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway&key=YOUR_KEY" | python3 -m json.tool | grep -E '(status|formatted_address)'

# Expected output:
# "status": "OK",
# "formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA"

If you still see 403, double-check that the curl command runs from the same IP/server environment that production uses (not your laptop).

Frequently Asked Questions

bash
#!/usr/bin/env bash
# google-maps-api-403-diag.sh
# Diagnose Google Maps API 403 and timeout errors
# Usage: API_KEY=your_key bash google-maps-api-403-diag.sh

set -euo pipefail
KEY="${API_KEY:-REPLACE_WITH_YOUR_KEY}"
BASE="https://maps.googleapis.com/maps/api"

echo "=== 1. Geocoding API health check ==="
curl -s "${BASE}/geocode/json?address=New+York&key=${KEY}" \
  | python3 -c "import sys,json; d=json.load(sys.stdin); print('STATUS:', d.get('status')); print('ERROR:', d.get('error_message','none'))"

echo ""
echo "=== 2. Places API health check ==="
curl -s "${BASE}/place/findplacefromtext/json?input=Google+HQ&inputtype=textquery&key=${KEY}" \
  | python3 -c "import sys,json; d=json.load(sys.stdin); print('STATUS:', d.get('status')); print('ERROR:', d.get('error_message','none'))"

echo ""
echo "=== 3. Directions API health check ==="
curl -s "${BASE}/directions/json?origin=New+York&destination=Boston&key=${KEY}" \
  | python3 -c "import sys,json; d=json.load(sys.stdin); print('STATUS:', d.get('status')); print('ERROR:', d.get('error_message','none'))"

echo ""
echo "=== 4. Check server outbound IP (for IP restriction whitelist) ==="
echo "Your outbound IP: $(curl -s https://api.ipify.org)"

echo ""
echo "=== 5. GCP — list enabled Maps APIs (requires gcloud auth) ==="
if command -v gcloud &>/dev/null; then
  PROJECT=$(gcloud config get-value project 2>/dev/null || echo 'NOT_SET')
  echo "Active project: ${PROJECT}"
  gcloud services list --enabled --filter="name:maps OR name:geocoding OR name:places OR name:directions" 2>/dev/null || echo 'gcloud not authenticated — skip'
else
  echo 'gcloud CLI not found — install from https://cloud.google.com/sdk'
fi

echo ""
echo "=== 6. Quota / rate limit stress test (5 rapid calls) ==="
for i in {1..5}; do
  STATUS=$(curl -s "${BASE}/geocode/json?address=Boston&key=${KEY}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('status','ERR'))")
  echo "  Call ${i}: ${STATUS}"
done

echo ""
echo "Diagnosis complete. If any STATUS is PERMISSION_DENIED: check billing + API enabled."
echo "If OVER_QUERY_LIMIT: implement back-off. If REQUEST_DENIED: check key restrictions."
E

Error Medic Editorial

The Error Medic Editorial team is composed of senior DevOps engineers, SREs, and cloud architects with combined experience across Google Cloud, AWS, and Azure. We specialize in API integration debugging, quota management, and production incident response. Our guides are written from real on-call experience and validated against official platform documentation.

Sources

Related Articles in Google Maps API

Explore More API Errors Guides