Nexus OSS 3.29.2-02推送Docker镜像报blob unknown错误的排查
报错信息的实际含义
errors: blob unknown: blob unknown to registry是Docker客户端收到的服务端通用校验失败返回,本身缺乏定位参考价值,对应的实际流程是:
- 客户端按照Docker镜像推送协议,完成所有镜像层的上传流程后,最后一步向Nexus提交该镜像的清单(Manifest)
- Nexus收到清单后会做合规校验:遍历清单中声明的所有镜像层,检查这些层是否在当前托管仓库的元数据索引中存在有效记录
- 当校验发现清单引用的层找不到有效记录时,就会返回这个通用的“blob未知”报错,因为错误提示做了通用化封装,没有直接点明缺失的具体层信息,才会出现提示无参考价值的情况。
结合Nexus侧的日志可明确对应关系:本次故障中报错提到的缺失层,就是日志里记录的两个sha256哈希对应的层,和推送过程中客户端跳过上传的层完全匹配。
异常触发的根本原因与解决措施
根本原因
该问题是Nexus OSS 3.29.2-02版本的已知兼容缺陷,完全匹配本次复现场景:
- 问题出在基于S3作为Blob存储后端的Docker托管仓库(也就是本次报错的
docker-hosted-s3仓库):该版本存在层上传流程的时序bug——第一次推送该镜像时,部分层的Blob对象已经成功写入S3存储,但对应的元数据记录没有和Nexus的Orient数据库完成关联 - 后续重复推送相同镜像时,Docker客户端会参考之前的推送状态,跳过这些“以为已经上传完成”的层,直接提交镜像清单
- Nexus收到清单提交请求后校验元数据,发现这些被跳过的层没有有效记录,就判定清单无效,返回校验失败。
结合排查过程可以排除其他可能诱因:
- 不是代理仓库拉取基础镜像的问题:其他项目使用相同的基础镜像构建推送均正常
- 不是Dockerfile逻辑复杂导致的问题:该Dockerfile逻辑极简,同结构的其他项目推送正常
- 不是客户端环境差异导致的问题:本地开发机、无状态CI节点复现的报错完全一致,说明故障源在服务端Nexus侧
- 日志中明确记录的“清单引用缺失层”的报错,完全匹配上述时序bug的故障特征。
解决措施
- 临时恢复单镜像推送:
- 在Nexus的
docker-hosted-s3仓库中,删除该故障标签(即snapshot-MR40对应的损坏清单记录),不要直接删除整个仓库的现有内容 - 在全新的无本地层缓存的Docker环境中导入该镜像(比如先在开发机用
docker save导出镜像为tar包,在干净的Docker环境中用docker load导入),再重新执行打标签、推送流程,让客户端全量上传所有层,跳过本地缓存判断的逻辑
- 在Nexus的
- 长期彻底修复:
将Nexus版本升级到3.30.1及以上版本,该版本已修复S3 Docker托管仓库中层Blob写入和元数据提交时序不一致的缺陷,从根本上避免后续出现同类单镜像持续推送失败的问题。
注:推送日志中提到的“registry v2 schema1支持将被移除”的弃用提示,和本次故障无关联,是独立的版本兼容提醒。
内容的提问来源于stack exchange,提问作者vkourt
相关产品推荐
相关产品推荐

