2026年2月9日、GitHub Actions の ubuntu-latest ランナーイメージが更新され、Docker が 28 → 29 にアップデートされた。
これにより、それまで正常に動作していた ECR (Amazon Elastic Container Registry) への docker push が突然 403 Forbidden エラーで失敗するようになった。
unknown:unexpectedstatusfromHEADrequestto
https://***.dkr.ecr.ap-northeast-1.amazonaws.com/v2/repo-name/manifests/0.1.99:
403Forbidden特徴的なのは、Docker イメージのレイヤーは全て正常に push されるにも関わらず、最後の manifest の push だけが 403 で失敗するという点。
Docker 29 では、containerd image store がデフォルトで有効になった。
従来の Docker (28以前) では、docker build で作成されたイメージは Docker 独自の image store に保存され、docker push は Docker Image Manifest V2 形式で push していた。
Docker 29 では、ビルドされたイメージが containerd の image store に保存される。この場合、docker push 時に生成される manifest の形式が変わり、ECR がこれを受け付けずに 403 Forbidden を返す。
ビルドログで確認できる兆候として、Docker 28 では見られなかった unpacking to ... という行が docker build の出力に現れる。これが containerd image store が使われている証拠。
# Docker 29 (containerd image store が有効な場合)
#20 naming to ***.dkr.ecr.../image:0.1.99 done
#20 unpacking to ***.dkr.../image:0.1.99 ← これが出る
#20 unpacking to ***.dkr.../image:0.1.99 3.2s done# Docker 28 (従来の image store)
#20 naming to ***.dkr.ecr.../image:0.1.95 done
← unpacking は出ないGitHub Actions の workflow ファイルで、Docker daemon の設定を変更して containerd snapshotter を無効化する。
steps:
-uses:actions/checkout@v3
-name:Disable containerd image store
run:|
DAEMON_JSON="/etc/docker/daemon.json"
if [ -f "$DAEMON_JSON" ]; then
sudo jq '. + {"features": {"containerd-snapshotter": false}}' "$DAEMON_JSON" \
| sudo tee "${DAEMON_JSON}.tmp" > /dev/null
sudo mv "${DAEMON_JSON}.tmp" "$DAEMON_JSON"
else
echo '{"features": {"containerd-snapshotter": false}}' \
| sudo tee "$DAEMON_JSON" > /dev/null
fi
sudo systemctl restart dockerubuntu-latest ランナーには /etc/docker/daemon.json が存在しない場合があるため、ファイルの存在確認が必要。存在しない場合は新規作成する。sudo systemctl restart docker で Docker daemon を再起動する必要がある。daemon.json がある場合は jq でマージすることで、他の設定を壊さないようにする。| 項目 | 成功時 (2025-12) | 失敗時 (2026-02) |
|---|---|---|
| ランナーイメージ | ubuntu24/20251215 | ubuntu24/20260209 |
| Docker | 28.0.4 | 29.1.5 |
| Docker Buildx | 0.30.1 | 0.31.1 |
| containerd image store | 無効 (デフォルト) | 有効 (デフォルト) |