跳到主要内容
DevOps2026-09-085 分钟阅读

docker pull 报 manifest unknown 怎么解决?tag 找不到的 4 种原因

现象:仓库在,tag 不在

Error response from daemon: manifest for myapp/api:v1.2.0 not found:
manifest unknown: manifest unknown

# 或拉 compose 依赖时
pull access denied(仓库级)
manifest unknown(tag 级)

一行结论:registry 认这个仓库,但找不到你写的那个 tag 对应的 manifest。manifest 是镜像的「目录页」(列出各架构的层信息),tag 指向 manifest——tag 错了或指向的东西不存在,就报这个错。

它和 pull access denied 是兄弟错误:denied 是仓库级问题(不存在/没权限),manifest unknown 是仓库内的 tag 级问题。看到 manifest unknown 说明仓库名多半是对的,盯住 tag 查。

四种原因,按概率排序

1. tag 拼写错误(最常见)

大小写敏感、v1.2 和 1.2 是两个 tag、- 和 _ 看混。最靠谱的核对方法——直接问 registry:

# 列出镜像的所有 tag(Docker Hub)
curl -s "https://hub.docker.com/v2/repositories/library/nginx/tags?page_size=20" | grep -o '"name":"[^"]*"'

# 或查特定 manifest 是否存在
docker manifest inspect myapp/api:v1.2.0

2. latest 陷阱:镜像根本没有 latest tag

docker pull myapp/api 省略 tag 时默认拉 latest。官方镜像基本都维护 latest,但个人/团队镜像经常只 push 过版本号 tag——docker push myapp/api:v1.2.0 不会自动创建 latest。写全 tag 就解决:

docker pull myapp/api:v1.2.0   # ✅ 显式 tag
docker pull myapp/api          # ❌ 拉不存在的 latest

3. 官方镜像改名/下架

镜像生态会变迁:仓库转移(旧仓库归档只读)、更名(如 amazonlinux)、或某版本 tag 被清理。如果你的 Dockerfile/文档是几年前写的,docker manifest inspect 确认一下,然后去 Hub 搜同名镜像看新家。

4. 架构不匹配:manifest 存在但没有你这个平台的

docker pull --platform linux/amd64 myapp/api:v1 时,如果该 tag 只 push 过 arm64 的 manifest,就会报 manifest unknown 或 no matching manifest。M 系列 Mac 用户交叉构建时高发:

# 看这个 tag 都有哪些架构
docker manifest inspect myapp/api:v1 | grep -A2 platform

# 构建时显式指定平台,保证目标架构存在
docker buildx build --platform linux/amd64 -t myapp/api:v1 --push .

exec format error(运行时架构不匹配炸掉)是这个问题没在 pull 阶段暴露的后果——拉的时候就要对齐平台。

排查路线(按顺序两分钟)

# 1. 列出仓库真实存在的 tag
curl -s "https://hub.docker.com/v2/repositories/<user>/<repo>/tags?page_size=50" | grep -o '"name":"[^"]*"'

# 2. tag 对但还报错?查 manifest 与架构
docker manifest inspect <完整镜像名:tag>

# 3. 省略 tag 拉的?补全 tag 再试
docker pull <完整镜像名>:<显式tag>

和相邻错误的分界

报错层级方向
manifest unknown / not foundtag 级本篇
pull access denied仓库级pull access denied 排查
no matching manifest for platform架构级本篇原因 4
exec format error运行时架构拉取阶段就该对齐平台

查 registry 里到底有什么

两条命令解决多数 manifest 争议而无需 pull。docker manifest inspect name:tag 打印 manifest 列表——多架构镜像列出 amd64/arm64 条目;单架构只有一条。列表缺你的平台时,pull 在错架构机器上就报这个错(经典:Apple Silicon 构建、amd64 CI 部署)。skopeo inspect 不需要 Docker daemon,CI 上没有 socket 时也行。先查再拉,把神秘运行时错误变成十秒读数。

buildx:让这类错不可能发生

如果你构建并分发镜像,修复在构建期:docker buildx build --platform linux/amd64,linux/arm64 --push 产出对两个平台都应答的 manifest 列表——整类错误对消费者消失。代价是跨架构构建的 QEMU 一次性设置。从笔记本构建的团队:buildx 不是可选工具——是「在服务器能用」和「只在构建机能用」的区别。

registry 三怪癖

Docker Hub 匿名拉取限流(高峰期 401/429 伪装成 manifest 失败);GHCR 要求大小写精确的 owner 名(ghcr.io/Owner/repo 写 owner 拒绝);自建 registry 在代理后面有时返回推送后的陈旧 manifest 缓存(重试或戳穿代理)。同一 tag 一台机器拉得动另一台拉不动,嫌疑是机器的 DNS/代理路径而不是 tag。

tag 与 digest:钉死你真正拉到的内容

tag 会漂移:myapp/api:v1 明天重建推送后可以指向另一份 manifest。digest 不会:

docker buildx imagetools inspect myapp/api:v1.2.0 --format '{{json .Manifest}}'
docker pull myapp/api@sha256:0123abcd…

Dockerfile 里可用 FROM myapp/api:v1.2.0@sha256:…(tag 给人看,digest 保可复现),或用 Dockerfile 生成器 生成带钉死基础镜像的模板。生产 Compose 只写浮动 tag,和「tag 被删」一样容易在周一早上变成 manifest unknown。

看起来像「tag 不存在」的鉴权噪音

私有 registry 有时把 401/403 改写成 manifest unknown / not found,避免泄露仓库是否存在。线索:

  • docker login 或换新 CI token 之后同一 tag 立刻能拉;
  • Hub 匿名限流(429)在高峰被客户端说成含糊的 pull 失败;
  • GHCR / 多数云 registry 要求路径里 owner 大小写完全一致。

若浏览器登录后 Tags 页看得到 tag,而 docker manifest inspect 报鉴权相关话术,先修凭证,别空转拼写排查。

Compose / CI:错误 tag 从哪混进来

image: myapp/api 不写 tag、${IMAGE_TAG} 为空、流水线构建 :sha-abc 却部署 :latest——这三种最常见。pull 前打印解析结果:

echo "pulling ${IMAGE:?IMAGE unset}"
docker compose config | grep 'image:'
docker pull "$IMAGE"

本机能拉、远端 agent 不能时,对比 daemon 架构(docker version)和 registry 镜像加速配置——镜像站可能缓存了过期或单架构的 manifest 列表。

排查清单

  1. tag 拼写逐字符核对(大小写、v 前缀、分隔符)
  2. 省略 tag = 拉 latest——这个镜像真的有 latest 吗?
  3. Hub Tags 页 / registry API 列出真实 tag 列表
  4. 指定了 --platform 的,确认该 tag 有对应架构的 manifest
  5. 老 Dockerfile 里的镜像名,确认仓库没改名/下架
  6. 鉴权 / 限流:docker login 后错误是否变化?
  7. 生产 FROM/pull 在 tag 解析成功后优先钉 digest

排查注记

排查主线盯 tag 不盯仓库名,依据是开头那条兄弟错误分界:pull access denied 是仓库级、manifest unknown 是 tag 级——看到 manifest unknown,仓库名多半已经对了。四种原因里 tag 拼写第一、latest 陷阱第二,因为 push 版本号 tag 不会自动创建 latest,而省略 tag 默认拉的就是这个不存在的标签。文末专门留了「鉴权噪音」一节,判断线索是 docker login 后同一 tag 立刻能拉——先修凭证,别空转拼写排查。


来自 ToolVault 工具匣 的开发手记。相关工具:Dockerfile 生成器、docker run 转 compose、Linux 命令速查。相关阅读:pull access denied 排查、Docker 磁盘爆满清理。访问 首页 查看更多开发者工具。