Apps Script: Exception: Request failed for ... returned code 4xx/5xx
Last verified
Exception: Request failed for https://api.example.com returned code 401. Truncated server response: {"error":"invalid_token"} (use muteHttpExceptions option to examine full response)What it means
UrlFetchApp.fetch throws this exception whenever the remote server answers with an HTTP error status. The request did reach the server and a response came back; the server rejected it. The number after returned code is the HTTP status, and the truncated response is the start of the server's own error body.
The status code tells you where to look. 400 means the request was malformed, 401 and 403 mean authentication or permission problems, 404 means a wrong URL, 429 means you are being rate-limited, and 5xx means the server failed.
Google's documentation says that with muteHttpExceptions: true the fetch does not throw when the response code indicates failure, and instead returns the response so you can read the full status and body.
What it looks like
const res = UrlFetchApp.fetch(url, {
method: 'post',
contentType: 'application/json',
headers: { Authorization: 'Bearer ' + token },
payload: JSON.stringify(body),
muteHttpExceptions: true
});
if (res.getResponseCode() >= 400) {
console.log(res.getResponseCode(), res.getContentText());
}Why it happens
- Missing, expired or wrongly formatted API key or bearer token (401, 403).
- Wrong endpoint, version or resource ID in the URL (404).
- Malformed JSON body or wrong contentType header (400, 415, 422).
- Too many requests to the API in a short time (429).
- The target site blocking requests from Google's servers (often 403).
- A temporary outage on the remote server (500, 502, 503).
How to fix it
- Set muteHttpExceptions: true and log response.getResponseCode() and response.getContentText() to see the full error.
- Compare the request with the API's documentation: method, URL, headers and payload.
- For POST JSON, set contentType: 'application/json' and send JSON.stringify(payload).
- For 401 and 403, regenerate or refresh the token and confirm the Authorization header format the API expects.
- For 429 and 5xx, retry with exponential backoff and respect any Retry-After header.
- Once fixed, keep checking the response code in code rather than relying on the exception.
How to stop it recurring
Wrap every external call in one helper that sets muteHttpExceptions, checks the status, logs failures with the response body, and retries only retryable codes (429 and 5xx) with backoff. Store credentials in script properties and validate them at the start of a run.
Official documentation: developers.google.com/apps-script/reference/url-fetch/url-fetch-app. See all Apps Script error messages or the Apps Script limits and quotas.
Related errors
- Exception: Address unavailableException: Address unavailable: https://example.com/api
- Service invoked too many times for one dayException: Service invoked too many times for one day: urlfetch.
- You do not have permission to call UrlFetchApp.fetchException: You do not have permission to call UrlFetchApp.fetch. Required…
Definitions
- Google Apps ScriptGoogle Apps Script is Google's cloud-hosted JavaScript platform for automating Google Workspace: Sheets, Gmail
- Error HandlingError handling is the practice of anticipating, detecting, and responding to errors in software execution, inc
- Rate LimitingRate limiting is a technique that controls the number of requests a client can make to a server within a given
- OAuth 2.0OAuth 2.0 is the IETF authorization standard (RFC 6749) that lets an app access your account in another servic
Quick answers
What does "Exception: Request failed for ... returned code 4xx/5xx" mean in Apps Script?
UrlFetchApp.fetch throws this exception whenever the remote server answers with an HTTP error status. The request did reach the server and a response came back; the server rejected it. The number after returned code is the HTTP status, and the truncated response is the start of the server's own error body. The status code tells you where to look.
How do I fix "Exception: Request failed for ... returned code 4xx/5xx"?
1. Set muteHttpExceptions: true and log response.getResponseCode() and response.getContentText() to see the full error. 2. Compare the request with the API's documentation: method, URL, headers and payload. 3. For POST JSON, set contentType: 'application/json' and send JSON.stringify(payload). 4. For 401 and 403, regenerate or refresh the token and confirm the Authorization header format the API expects. 5. For 429 and 5xx, retry with exponential backoff and respect any Retry-After header. 6. Once fixed, keep checking the response code in code rather than relying on the exception.
Run the job somewhere with its own limits
If a script keeps hitting its host's quotas, an Autonoly workflow can run the same steps on a schedule in an isolated cloud container, and the AI agent has a terminal with Python for steps that need code. Autonoly has limits of its own, priced in credits.
Also see Agent terminal & SSH.