Gemini API errors look numerous, but in practice most fall into four categories: wrong identity, wrong address, insufficient quota, and an unreachable network. Problems caused by the model itself are comparatively rare.
This article breaks down each error code and provides a troubleshooting sequence that starts from a minimal request. When something fails, save the complete error JSON first, then check items in order. Do not change the key, the address, and the model at the same time.
Note: Google and Gemini are trademarks of their respective owners. This article describes common API shapes as of October 2026. Interface versions, quotas, and regional policies follow the official documentation and the model pricing page.
1. Learn to read the error body
Google APIs usually return errors as JSON with three key fields:
{
"error": {
"code": 429,
"message": "Quota exceeded for quota metric ...",
"status": "RESOURCE_EXHAUSTED"
}
}
code is the HTTP status code, status is the machine-readable error type, message often contains the specific cause, and details may include a quota ID and a suggested retry time. Read all of them. Looking only at "429" will not tell you whether you hit a per-minute limit or exhausted a daily quota.
| Status | Common status value | General direction |
|---|---|---|
| 401 | UNAUTHENTICATED | Key missing, invalid, or in the wrong place |
| 403 | PERMISSION_DENIED | API not enabled, permission issue, or region restricted |
| 404 | NOT_FOUND | Wrong model name, endpoint path, or version |
| 429 | RESOURCE_EXHAUSTED | Rate, concurrency, or quota exceeded |
| 400 | INVALID_ARGUMENT / FAILED_PRECONDITION | Bad parameters, unsupported region, or unmet precondition |
| 500/503 | INTERNAL / UNAVAILABLE | Temporary upstream failure; usually safe to retry with backoff |
2. 401: invalid key or wrong authentication method
The core meaning of a 401 is "the server does not recognize your identity." Common causes:
- The request does not include a key at all, or the environment variable is empty.
- The native API uses
Authorizationinstead ofx-goog-api-key. - The OpenAI-compatible API uses
x-goog-api-keyinstead ofAuthorization: Bearer. - The key has leading or trailing spaces or line breaks, or quotes were copied along with it.
- The key was deleted or rotated, or its project was disabled.
- A gateway key was sent to Google's official address, or the reverse.
- The key has API restrictions that do not allow calls to the Gemini API.
Confirm with a minimal request first:
export GEMINI_API_KEY="your-key"
# Native Gemini API
curl "https://generativelanguage.googleapis.com/v1beta/models/<MODEL_ID>:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contents":[{"parts":[{"text":"Reply with OK only"}]}]}'
# OpenAI-compatible API
curl "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions" \
-H "Authorization: Bearer $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"<MODEL_ID>","messages":[{"role":"user","content":"Reply with OK only"}]}'
The two commands use two authentication schemes. Whichever one works tells you which system your key and address belong to. A 401 from mixing them does not mean the key is broken; the combination is wrong.
3. 404: wrong model name, path, or version
A 404 does not necessarily mean the model does not exist. Common cases include:
- The model ID is misspelled, or the console display name was used instead of the API identifier.
- The model does not belong to the current API version—for example, sending a model available only in a newer version to an older path.
- The base URL includes an extra or missing
/v1or/v1beta, so path concatenation produces a nonexistent address. - A trailing slash on the base URL causes the client to append the path twice.
- When calling through a gateway, the model is not enabled in the current group or plan.
- A chat endpoint is being used to call image generation or another specialized API.
Start by listing the models available to the current key:
curl "https://generativelanguage.googleapis.com/v1beta/models" \
-H "x-goog-api-key: $GEMINI_API_KEY"
If the target model appears in the list, verify the request path. If it does not, resolve model access or permission issues first. When calling through a gateway, use the model ID and base URL from the gateway documentation rather than assuming official model names will work.
4. 429: distinguish rate limiting from quota exhaustion
429 is the error most often misdiagnosed. It covers at least three situations:
| Type | Typical sign | Direction |
|---|---|---|
| Per-minute rate limit | High concurrency in a short window; errors cluster within seconds | Reduce concurrency; back off and retry |
| Daily quota exhausted | The day's usage reached the cap and failures continue | Wait for the reset, raise the quota, or change approach |
| Project-level quota | Several services share one project and compete for quota | Split projects or keys and give each its own quota |
The details field usually gives the quota ID and a suggested retry time. Do not resend immediately whenever you see a 429; a retry storm makes things worse. Install the dependency first with pip install requests. Here is a workable backoff routine:
import random
import time
import requests
def generate(prompt: str, retries: int = 4):
url = "https://generativelanguage.googleapis.com/v1beta/models/<MODEL_ID>:generateContent"
headers = {
"x-goog-api-key": "your-key",
"Content-Type": "application/json",
}
for attempt in range(retries):
resp = requests.post(
url,
headers=headers,
json={"contents": [{"parts": [{"text": prompt}]}]},
timeout=60,
)
if resp.status_code == 200:
return resp.json()
if resp.status_code not in (429, 500, 503):
resp.raise_for_status()
wait = min(2 ** attempt, 30) + random.random()
time.sleep(wait)
raise RuntimeError("Retries exhausted")
Retries only solve temporary congestion; they cannot fix an exhausted quota. Production also needs timeouts, circuit breaking, and a fallback model. Otherwise one 429 can take down the whole chain.
5. Region blocks: why direct access fails from some countries
The Gemini API is available only in certain countries and regions. When the request egress lands in an unsupported region, there are three common symptoms:
- Connection timeouts or TLS handshake failures, usually because the network path is blocked.
- A
400 FAILED_PRECONDITIONresponse with text such as "location is not supported." - A
403 PERMISSION_DENIEDresponse, which may relate to the project, billing, or regional permissions.
Two concepts are easy to confuse here: the account registration region and the request egress region. Even if the account itself is valid, a server deployed in an unsupported region may still have its requests rejected. Conversely, being able to open a web page through a local proxy does not mean API requests take the same route.
A recommended order of handling:
- Confirm whether the request originates from your machine, a container, or a server, and find the real egress IP.
- Check whether the egress region is on the official supported list.
- Review the cloud server's region selection and move to a supported region if necessary.
- If the business operates mainly in mainland China, evaluate a compliant gateway to handle networking and billing in one place.
- Do not treat "change the IP" as the only solution. Confirm the service terms and local regulatory requirements first.
6. Other common errors
| Symptom | Common cause | Action |
|---|---|---|
| 400 INVALID_ARGUMENT | Malformed JSON, wrong role order, unsupported image format | Start from a minimal request and add fields one at a time |
| 400 FAILED_PRECONDITION | Unsupported region, billing not enabled, missing precondition | Check the region, billing, and project status |
| 403 PERMISSION_DENIED | API not enabled, key restrictions, insufficient project permission | Enable the API in the console and verify permissions |
| 500 INTERNAL | Internal upstream error | Back off and retry; record the request ID |
| 503 UNAVAILABLE | Upstream overload or maintenance | Back off and retry; switch to a fallback model |
| Response but no content | Safety policy block or truncated output | Check blockReason and finishReason |
| Output stops midway | Maximum output tokens reached | Raise the limit or shorten the input |
"Response but no content" is often mistaken for a failure, when it is actually safety filtering or a length limit. Check promptFeedback.blockReason, finishReason, and usageMetadata in the response before deciding whether to change the prompt or adjust parameters.
7. Recommended troubleshooting order
- Save the complete error JSON, request time, model ID, and request ID.
- Send a minimal request with curl to rule out the client and SDK.
- Verify three things: the base URL, the authentication header, and the model ID.
- Switch to a model known to work and determine whether the problem is the model or the connection.
- Check quota, billing, and project status, and distinguish 429 from 403.
- Confirm the request egress region and network path.
- Finally, review client configuration, proxy settings, and retry logic in the code.
Change one variable at a time. Otherwise, even if service recovers, you will not know which change fixed it—and you will hit the same problem again.
8. FAQ
What is the difference between 401 and 403?
A 401 means authentication failed; check the key, the authentication header, and whether the address matches. A 403 means authentication succeeded but permission is missing; check whether the API is enabled, project permissions, key restrictions, and regional policy.
Can I just wait a few minutes after a 429?
It depends on the quota type. Per-minute rate limits usually recover after backoff; an exhausted daily quota requires a reset or a quota increase. Read the quota ID and retry suggestion in the error body instead of resending blindly.
Does changing my IP solve a region block?
Not necessarily. It depends on the real egress region, the account status, and the service terms. For enterprise workloads, a more reliable approach is to deploy in a supported region or use a compliant gateway.
The official address works, but the gateway returns 404. Whose problem is it?
Check the gateway's base URL and model ID first. A gateway may use different model naming, paths, and availability from the official API, so official requests cannot simply be reused. Replace each field using the minimal example in the gateway documentation.
How do I keep retries from multiplying costs?
Set a maximum retry count, exponential backoff, and a timeout. Handle 429 separately. Add deduplication for non-idempotent requests. Set budget ceilings and alerts on the gateway side.
Next steps
The key to Gemini troubleshooting is to separate authentication, path, quota, and network issues, then verify each with a minimal request. If you need a unified entry point and want to reduce the uncertainty of direct access from mainland China, sign up for the ZSQH AI Gateway. Models, quotas, and prices follow the model pricing page.
Related reading:
