シェル / CI: curl は 404 でも成功扱い。-f(--fail)でHTTPエラーを失敗にする
curl は HTTP 404 や 500 が返っても通信自体ができていれば終了コード 0 を返す。-f を付けると 400 以上のステータスで終了コード 22 になり、CI やスクリプトがそこで止まる。
何が起きるか
bash
curl -o tool.tar.gz https://example.com/releases/v1.2.3/tool.tar.gz
echo $? # URL を間違えて 404 でも 0
tar xzf tool.tar.gz # 中身はエラーページの HTML なのでここで謎の失敗ダウンロードしたつもりのファイルが実はエラーページで、ずっと後の手順で分かりにくいエラーになる。curl ... | bash の場合はエラーページの HTML をシェルが実行しようとする。
やり方
bash
# 400 以上なら終了コード 22 で止まる
curl -fsSL -o tool.tar.gz https://example.com/releases/v1.2.3/tool.tar.gz
# 失敗してもレスポンス本文は見たい(API のエラーメッセージなど): curl 7.76.0+
curl --fail-with-body -sS https://api.example.com/items- インストール手順でよく見る
-fsSLは、-f(HTTP エラーで失敗)、-s(進捗を出さない)、-S(-sでもエラーは表示)、-L(リダイレクトに従う)の組み合わせ。 -fだけだと失敗時の本文は捨てられる。原因を知りたいときは--fail-with-body。
注意点
-fは「HTTP のステータスが 400 以上」だけを見る。200 で中身が壊れている場合は防げないので、配布物はチェックサムも確認する。curl ... | bashでは curl が失敗しても、パイプの終了コードは bash 側になる。set -o pipefailを付けるか、いったんファイルに保存してから実行する(シェル: curl … | bash を | bashka に変えて、実行前にスクリプトを静的検査する も参照)。- 認証エラー(401/407)など一部のケースでは
-fでもヘッダーの一部が出力されることがある、と curl のマニュアルに注記がある。
出典
- @tane_log · 2026-10-26
- curl マニュアル
--fail/--fail-with-body: curl.se/docs/manpage.html#-f