error.code and error.status fields to identify the problem programmatically and surface a meaningful message to your users or alerting system.
Error Response Structure
Every error — regardless of status code — follows the same envelope format. Familiarize yourself with this shape before reading the per-code reference below.Error Response Schema
object
required
Top-level error container. Always present when the HTTP status code is not
2xx.Quick Reference
Error Code Details
400 — Bad Request
400 — Bad Request
400 Bad Request
A400 means the request was structurally invalid before Google attempted to process it. The most common causes are a missing required parameter (key, cx, or q), a parameter value that falls outside the accepted range, or conflicting parameter combinations.error.status: INVALID_ARGUMENTExample — Missing q parameter
Example — start value out of range
How to resolve
- Check that
key,cx, andqare all present in the request. - Verify that
numis between1and10and thatstartis between1and91. - Ensure
searchType,safe,imgSize,imgType, and other enum parameters use only documented values. - URL-encode the
qvalue — unencoded special characters can truncate or corrupt the query string.
403 — Forbidden (permission / quota)
403 — Forbidden (permission / quota)
403 Forbidden
A403 covers two distinct scenarios: permission problems (the key exists but is not allowed to make this call) and quota exhaustion (the key is valid but has hit a usage limit). Distinguish between them using error.status.Scenario A — Permission denied
error.status: PERMISSION_DENIEDCommon causes: the Custom Search API is not enabled in the project, an API restriction blocks this API, or an application restriction blocks the caller’s IP/referrer/app.- Enable the Custom Search API for your project at console.developers.google.com/apis/api/customsearch.googleapis.com.
- If you have API restrictions on the key, ensure Custom Search API is in the allowlist.
- If you have IP or referrer restrictions, confirm the request originates from an allowed source.
- Wait up to 5 minutes after making changes for them to propagate.
Scenario B — Quota exhausted
error.status: RESOURCE_EXHAUSTEDThe project has consumed its daily or per-minute query budget.- The free tier provides 100 queries/day per project. If you need more, enable billing and purchase additional query capacity (up to 10,000 queries/day per project).
- Check your current usage at Cloud Console → APIs & Services → Quotas.
- Implement client-side caching to reduce duplicate queries.
- Distribute load across multiple projects (each has its own free tier quota) if your use case permits.
404 — Not Found
404 — Not Found
404 Not Found
A404 typically means the Search Engine ID (cx) you supplied does not exist, has been deleted, or belongs to a different Google account.error.status: NOT_FOUNDExample
How to resolve
- Log into programmablesearchengine.google.com and confirm the Search Engine ID shown in Setup → Basics → Search engine ID matches the
cxvalue you are passing. - Search Engine IDs are case-sensitive. Copy-paste the value rather than typing it manually.
- If you are using a
cxcreated by another user, ensure they have shared it with your account. - If you deleted the search engine, create a new one and update your configuration.
429 — Too Many Requests
429 — Too Many Requests
429 Too Many Requests
A429 means you have exceeded the per-second or per-minute request rate limit, separate from the daily quota. This is a transient error — slow down and retry.error.status: RESOURCE_EXHAUSTEDExample
How to resolve
Implement truncated exponential backoff:- After the first
429, wait 1 second and retry. - After each subsequent failure, double the wait time (1 s → 2 s → 4 s → 8 s …).
- Add a small random jitter (e.g., ±500 ms) to prevent retry storms when many clients hit the limit simultaneously.
- Cap the maximum wait at 32–64 seconds.
- After 5–7 retries without success, surface an error to the user rather than retrying indefinitely.
500 — Internal Server Error
500 — Internal Server Error
500 Internal Server Error
A500 indicates a transient problem on Google’s infrastructure. The request was valid — the error is not caused by anything in your code. Retry with backoff.error.status: INTERNALExample
How to resolve
- Retry the identical request after a short delay (start with 2 seconds).
- Use the same exponential backoff strategy as for
429errors. - If
500errors persist for more than a few minutes, check the Google Cloud Status Dashboard for an active incident affecting the Custom Search API. - Log the full error body and the request parameters (excluding the API key) so you can file a support ticket if needed.
A
500 does not count against your daily quota. You will not be charged for requests that return 500.Recommended Error Handling Pattern
Structure your error handling to branch on HTTP status code first, then onerror.status for cases where a single status code covers multiple distinct problems (such as 403).
Related Pages
API Overview
Base URL, required parameters, and response shape for the Custom Search JSON API.
Authentication
How to create, pass, restrict, and rotate API keys. Includes credential error examples.