Skip to content
Google Apps Script · error message

Apps Script: Exception: Request failed for ... returned code 4xx/5xx

ConfigurationUrlFetchApp and external requests

Last verified

The exact message
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

  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.

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

Definitions

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.