Skip to main content
DevOps Insightsguides & answers

curl · troubleshooting

curl: (22) The requested URL returned error

The server answered with an HTTP error (400 or above) and curl was run with -f or --fail, so it exited 22 instead of saving the error page. The number after error: is the HTTP status, and it tells you what to fix.

Reproduced on curl 8.5.0, . Where the text says “reproduced”, the behaviour was run on that version, not taken from documentation.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 8 sections

Before you start

  • The full message including the status code, and the URL the script built.

Run this first

step 1 of 1
curl -sS --fail-with-body -D - "$URL"

Look for The status line and the body's explanation

Shows the status, headers and the server's error body while still exiting 22.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

Which status follows error:?

Cause space

3 of 3 still possible

  • 404: the URL is wrong or the file does not existCommon
  • 401 or 403: missing credentials or no permissionCommon
  • 5xx: the server failedOccasional

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    curl -sS --fail-with-body -D - "$URL"

    Shows the status, headers and the server's error body while still exiting 22.

    Look for The status line and the body's explanation

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

404: the URL is wrong or the file does not exist

Common

A version or path variable that is empty or wrong, a release asset that was renamed, or a download from a branch or tag that does not exist.

Confirm

echo "$URL"
curl -sS --fail-with-body "$URL" | head -c 300

A malformed URL, or the server's explanation in the body

Fix

  • Correct the URL; print it in the script while debugging, and fail early when a variable that builds it is empty.

401 or 403: missing credentials or no permission

Common

A token that is not passed, expired, or lacks access to this resource; a private repository or registry.

Confirm

curl -sS -o /dev/null -D - "$URL" | grep -iE '^HTTP/|^www-authenticate'

401 with www-authenticate (credentials) or 403 (permission)

Fix

  • On 401, send the right credential: check the header name, the token's scope and that the variable is set in this job.
  • On 403, grant the identity access, or check what is in front of the service.

5xx: the server failed

Occasional

The service or a proxy in front of it failed; often temporary.

Confirm

curl -sS --fail-with-body "$URL"

500, 502, 503 or 504 and the body's message

Fix

  • Retry with --retry, which treats 500, 502, 503 and 504 as transient; if it persists, the server needs fixing.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

With -f, curl treats an HTTP error as a failure, which is what you want in scripts. The real information is the status code at the end of the message: 404 means the URL is wrong or the file is not there, 401 or 403 means credentials or permission, 5xx means the server failed.

Words used on this page

-f, --fail
Exit 22 on HTTP errors and write no response body.
--fail-with-body
Exit 22 on HTTP errors but still print the body, which usually says why.
What is actually happening

Reproduced on 23 October 2026 with curl 8.5.0 on Ubuntu 24.04 and curl 8.7.1 on macOS, against a local server that answered 404. curl -f printed curl: (22) The requested URL returned error: 404, exited 22 and wrote no output file.

Without -f, the same request exited 0 and saved the server's error body as if it were the download. A script that fetches an artifact that way carries on with a file containing an error message, and fails later somewhere confusing.

--fail-with-body exited 22 too, but printed the body, here {"error":"artifact v1.2.3 not found"}. That is usually the fastest way to the cause.

How to tell this is your problem
WhereWhat you see
curl -f in a script or CI stepcurl: (22) The requested URL returned error: 404
Authentication problemscurl: (22) The requested URL returned error: 401

How to know it is actually fixed

  • curl -f exits 0 and the downloaded file is the expected content, not an error page.

Stopping it happening again

  • Always use -f or --fail-with-body for downloads in scripts; without them an error page counts as success.
  • Prefer --fail-with-body in CI so the log shows why the server refused.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it