症状

docker push 実行時に layer already exists と表示されるが、プッシュが完了しない、またはエラーで失敗する。

結論:まずこれを確認

  1. docker login で認証が正しく行われているか確認する
  2. プッシュ先のタグが既存イメージと競合していないか確認する
  3. ローカルイメージのタグとリモートリポジトリ名が一致しているか確認する

トラブルシューティングフロー

    flowchart TD
    A[docker push 失敗] --> B{認証エラー?}
    B -->|Yes| C[docker login を実行]
    B -->|No| D{タグ名は正しい?}
    D -->|No| E[docker tag で正しい名前を付与]
    D -->|Yes| F{denied エラー?}
    F -->|Yes| G[リポジトリの権限を確認]
    F -->|No| H{retrying エラー?}
    H -->|Yes| I[ネットワーク・レジストリ状態確認]
    H -->|No| J[キャッシュクリアを検討]
    C --> K[再度 push を実行]
    E --> K
    G --> K
    I --> K
    J --> K
  

よくある原因

  • 認証の期限切れ - docker login のセッションが切れている
  • タグ名の不一致 - ローカルイメージのタグがリモートリポジトリ名と一致していない
  • 権限不足 - リポジトリへの push 権限がない
  • レジストリ側の不整合 - リモートに同名レイヤーが破損状態で存在する
  • ネットワークタイムアウト - 大きなレイヤーのアップロード中に接続が切れる
  • ディスク容量不足 - レジストリ側のストレージが不足している
  • プロキシ設定の問題 - 企業ネットワーク等でプロキシが必要

確認手順

ステップ1: 認証状態を確認する

    docker login <レジストリURL>
  

🔍 チェックポイント: Login Succeeded が表示されれば認証は正常

認証情報を確認する場合:

    cat ~/.docker/config.json
  

ステップ2: イメージのタグを確認する

    docker images | grep <イメージ名>
  

🔍 チェックポイント: タグが レジストリURL/リポジトリ名:タグ の形式になっているか確認

タグを付け直す場合:

    docker tag <イメージID> <レジストリURL>/<リポジトリ名>:<タグ>
  

ステップ3: push を詳細モードで実行する

    docker push <イメージ名>:<タグ> 2>&1 | tee push.log
  

🔍 チェックポイント: どのレイヤーで止まっているか、エラーメッセージの詳細を確認

ステップ4: レジストリの状態を確認する

Docker Hub の場合:

    curl -s https://hub.docker.com/v2/repositories/<ユーザー名>/<リポジトリ名>/tags | jq .
  

プライベートレジストリの場合:

    curl -s -u <ユーザー名>:<パスワード> https://<レジストリURL>/v2/<リポジトリ名>/tags/list
  

🔍 チェックポイント: リモートに同名タグが存在するか確認

ステップ5: ローカルキャッシュをクリアして再ビルドする

    docker system prune -a
docker build --no-cache -t <イメージ名>:<タグ> .
docker push <イメージ名>:<タグ>
  

🔍 チェックポイント: 新しいレイヤーIDで push が進むか確認

ステップ6: 特定レイヤーの問題を切り分ける

マニフェストを確認する:

    docker manifest inspect <イメージ名>:<タグ>
  

🔍 チェックポイント: no such manifest ならリモートに存在しない、マニフェストが返ればリモートに存在する

NG行動(やってはいけないこと)

  • --force オプションを安易に使う - 他のタグに影響する可能性がある
  • 認証情報をコマンドラインに直接記載する - シェル履歴に残りセキュリティリスクになる
  • エラーを無視して繰り返し push する - レジストリ側の問題は解決しない
  • 本番レジストリで検証なく操作する - 既存イメージを破損させる可能性がある

よくある質問(FAQ)

Q1: layer already exists は正常なメッセージでは?

A: 正常な場合もある。既存レイヤーをスキップして効率化している表示。ただし、その後にエラーが出る、または push が完了しない場合は問題がある。

Q2: マルチアーキテクチャイメージで同じエラーが出る場合は?

A: docker buildx build --push を使用する。--platform オプションでアーキテクチャを明示し、マニフェストリストが正しく作成されているか確認する。

Q3: CI/CD 環境でのみ発生する場合は?

A: CI 環境の認証設定を確認する。docker login がジョブ内で正しく実行されているか、環境変数 DOCKER_CONFIG が適切か確認する。

関連するエラー・症状

  • (関連記事準備中)
  • (関連記事準備中)
  • (関連記事準備中)

解決しない場合

公式ドキュメント

確認すべきログ

  • Docker デーモンログ: journalctl -u docker.service
  • レジストリ側のログ(アクセス可能な場合)

次に調べるキーワード

  • docker push timeout
  • docker registry layer conflict
  • docker manifest invalid