冒頭まとめ

manifest unknown は、レジストリとの通信自体は成立しているのに、指定した image reference(タグまたはダイジェスト)に対応する manifest がそのリポジトリで解決できなかったときに出るエラーです。OCI Distribution Specification では、リポジトリに blob または manifest が見つからない場合の応答は 404 Not Found と定められており、この系統のエラーは「サーバーが壊れている」ではなく「参照先が存在するか」を疑うところから始めます(OCI Distribution Specification)。

調査は次の3点を順に確認するのが最短です。

  1. 指定したタグまたはダイジェストが、そのリポジトリに実在するか
  2. image reference の各要素(レジストリホスト、名前空間、リポジトリ名、タグ、プラットフォーム)が意図したものになっているか
  3. 直前の build・tag・push、マルチアーキテクチャの manifest 公開が本当に完了しているか

エラーの概要

manifest unknown は、レジストリが「そのリポジトリに、要求された manifest がない」と応答している状態です。名前解決や TLS の失敗とは違い、リクエストレジストリまで届いています。認証エラーとも異なり、レジストリリクエストを受け付けたうえで「該当なし」を返しています。

近いエラーとの違いを整理すると、次のように分類できます。

出力の傾向意味するもの最初に見る場所
manifest unknown(manifest が見つからない)参照先のタグ・ダイジェストが存在しないimage reference とタグ一覧
denied / unauthorized などの権限系の文言認証認可が足りない、または対象が非公開ログイン状態とアクセス権
接続タイムアウト、名前解決失敗、証明書エラーレジストリまで到達できていないネットワークプロキシTLS 設定
500・502・503・504レジストリ側の障害レジストリの稼働状況

なお、非公開リポジトリに対して存在を隠すために「見つからない」相当の応答を返すレジストリもあります。権限系と参照先不在の切り分けで迷う場合は、対象レジストリの公式ドキュメントで応答の仕様を確認してください。

本記事が扱う範囲は、docker pulldocker push の時点で発生する、レジストリ上の manifest 解決失敗です。認証認可エラーレジストリへの到達性そのものの問題、および Kubernetes の Pod sandbox 作成段階のイベントFailedCreatePodSandbox など)は、発生する層が異なるため本記事の対象外とします。

エラーメッセージの読み方

このエラーの出力には、原因を絞り込むための情報が2つ含まれています。

文言そのものは、クライアントレジストリの実装や版によって異なります。ここで例文を暗記するのではなく、手元の実際の出力をそのまま基準にしてください。読むときのポイントは次のとおりです。

  • reference を要素ごとに分解する:<registry>/<namespace>/<image>:<tag> のどこが自分の想定と違うかを見る
  • 出力に latest が現れている場合、タグを省略したために暗黙で latest が補われた可能性を疑う
  • @sha256: で始まるダイジェスト参照が出ている場合は、ダイジェストの取り違えや、参照先 manifest が既に存在しないケースを疑う
  • プラットフォームの不一致は manifest unknown とは別の文言になることがあります。判断は実際の出力の文言で行ってください

原因と解決策

早見表

原因主な確認対処
タグが存在しない、latest が公開されていないタグ一覧、docker manifest inspect実在するタグを明示して pull する
image reference の指定違い(ホスト、名前空間、名前、プラットフォーム)reference の各要素、認証済みアカウントreference を完全な形で指定し直す
push や manifest 公開が未完了CI/CDログ、push 後のタグ確認公開を完了させてから pull する

原因1:指定したタグがリポジトリに存在しない

タグ名の打ち間違い、タグ削除や付け替え、そしてタグを省略して latest が暗黙に指定されるケースが典型です。リポジトリlatest を公開していないプロジェクトは珍しくありません。

対処は、reference を省略せずに指定し、存在するタグを確認することです。

# タグを明示して pull する
docker pull <your-registry>/<your-namespace>/<your-image>:<your-tag>

# 指定した reference の manifest が存在するかを確認する
docker manifest inspect <your-registry>/<your-namespace>/<your-image>:<your-tag>

タグの一覧は、対象レジストリの管理画面か、OCI Distribution Specification で定義されているタグ一覧の API で確認します。エンドポイントの正確な形式は、上記の仕様書と各レジストリの公式リファレンスで確認してください。

docker manifestクライアントの版によって利用可否や構文が異なることがあるため、実行前に手元で確認しておくと確実です。

docker manifest --help
docker manifest inspect --help

原因2:image reference が意図した対象を指していない

レジストリホストの誤り、名前空間や組織名の誤り、似た名前のリポジトリ、そしてプラットフォーム指定の不一致により、意図した manifest list や image manifest とは別の対象を参照している場合があります。レジストリホストを省略したときの既定の参照先は、クライアントとその設定によって変わります。切り分け中は省略せず、完全な形で指定してください。

# レジストリホストから明示して確認する
docker manifest inspect <your-registry>/<your-namespace>/<your-image>:<your-tag>

docker manifest inspect の出力で、対象が manifest list(マルチアーキテクチャ)である場合は、含まれるプラットフォームの一覧を確認できます。目的のプラットフォームが含まれていなければ、pull 側の指定を変えるより、公開側に必要なアーキテクチャを追加するのが本筋の対処です。

また、対象が非公開の場合は、認証済みのアカウントがそのリポジトリを参照できるかどうかも切り分け対象になります。

docker login <your-registry>

原因3:参照先の manifest がレジストリに存在しない

ビルドや push の途中失敗、マルチアーキテクチャ manifest の未作成、タグ付け忘れによって、pull しようとしている manifest がまだ公開されていないケースです。

ここは仕様上の裏付けがあります。OCI Distribution Specification では、push はイメージを構成する blob を先に、manifest を最後にアップロードする順序が一般的とされています。つまり push が途中で失敗すると、blob だけが存在して manifest が未登録という状態が起こり得ます。ログ上は「アップロードが進んでいた」ように見えても、タグは解決できません(OCI Distribution Specification)。

対処は、公開側の工程を順序どおりに完了させ、公開を確認してから pull することです。

# 1. タグを付ける
docker tag <your-local-image> <your-registry>/<your-namespace>/<your-image>:<your-tag>

# 2. push する(終了コードと出力を必ず確認する)
docker push <your-registry>/<your-namespace>/<your-image>:<your-tag>

# 3. レジストリ側で解決できることを確認する
docker manifest inspect <your-registry>/<your-namespace>/<your-image>:<your-tag>

マルチアーキテクチャで配布する場合は、各アーキテクチャのイメージを push したうえで、manifest の作成と公開まで終える必要があります。構文は版により異なるため、docker manifest create --helpdocker manifest push --help で確認してから実行してください。CI/CD では、build → tag → push → manifest 作成 → manifest 公開の順序と、各ステップの終了コードをパイプラインのログで確認します。前段が失敗しているのに後段が走っている構成では、このエラーが再発します。

確認・切り分け手順

上から順に実行すると、原因を機械的に絞り込めます。

  1. 実際の出力を保存する:文言と reference を一字も変えずに記録します。ここが以降の判断材料になります。

    docker pull <your-registry>/<your-namespace>/<your-image>:<your-tag>
    
  2. エラーの種類を分類するmanifest unknown なのか、権限系の文言なのか、接続エラーなのか、5xx なのかを確認します。権限系や接続系であれば、本記事ではなくそれぞれの原因を追います。

  3. reference を完全な形にして再試行する:レジストリホスト、名前空間、リポジトリ名、タグをすべて明示します。ここで成功した場合、原因は省略時の既定値(latest や既定レジストリ)でした。

  4. manifest の存在を直接確認する

    docker manifest inspect <your-registry>/<your-namespace>/<your-image>:<your-tag>
    
    • 成功する場合:参照先は存在します。プラットフォーム指定や、pull を実行している環境側の設定を疑います
    • 失敗する場合:参照先が存在しません。タグ一覧と公開側の工程を確認します
  5. タグ一覧と突き合わせるレジストリの管理画面またはタグ一覧 API で、実在するタグを列挙して比較します。

  6. ダイジェストで確認するタグではなくダイジェストで解決できるかを試すと、タグの付け替えと manifest 自体の不在を切り分けられます。

    docker manifest inspect <your-registry>/<your-namespace>/<your-image>@sha256:<your-digest>
    
  7. ローカルの状態と混同していないか確認する:手元にあるイメージと、レジストリ上の公開状況は別です。

    docker image ls --digests
    
  8. 公開側のログを確認するCI/CD の push ステップが成功しているか、manifest の公開まで到達しているかを確認します。

対処後は、手順4と手順1を再実行し、docker manifest inspect が manifest を返し、docker pull が完了することを確認してください。

それでも解決しない場合

原因が絞り込めないときは、次の情報を揃えてから問い合わせや調査を進めると早く進みます。

そのうえで、次の点も確認してください。

なお、認証を外す、TLS 検証を無効にする、意図しないタグlatest として上書きするといった操作は、原因の解消ではなく別の問題を持ち込みます。切り分けの主手段にはしないでください。


免責事項:本記事の内容は、執筆時点の公開情報をもとに作成したものです。ソフトウェアの仕様は予告なく変更されることがあります。最新の情報は各ツールの公式サポートページをご確認ください。本記事の情報を利用した結果生じたいかなる損害についても、著者および運営者は責任を負いかねます。