You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Docker /v2/{name}/manifest/{tag} API推送镜像时报manifest invalid错误如何解决

问题修复方案

核心错误原因

你遇到的manifest invalid, invalid format length错误来自两个代码逻辑的共性问题:发送的manifest内容被错误转义/修改,以及Content-Type和实际manifest格式不匹配。


Shell脚本错误点&修复

错误点

curl的-d参数使用了单引号包裹$manifests变量,且额外加了多余双引号:

  • 单引号内的shell变量不会展开,实际发送的是字面量"$manifests",而非真实的manifest内容
  • 多余的双引号会额外增加无效字符,导致manifest格式校验失败

修复后的代码

#! /bin/bash
getManifestsUrl="http://localhost:5001/v2/registry/manifests/1"
putManifestsUrl="http://localhost:5002/v2/registry/manifests/1"
# 先获取manifest和对应的Content-Type
contentType=$(curl -s -I "$getManifestsUrl" | grep -i 'content-type' | awk -F': ' '{print $2}' | tr -d '\r')
manifests=$(curl -s -X GET "$getManifestsUrl")
echo "$manifests"
# PUT时直接传递原始manifest,使用源返回的Content-Type
result=$(curl -X PUT -H "Content-Type:$contentType" -d "$manifests" "$putManifestsUrl") 
echo "$result"

Java代码错误点&修复

错误点

  1. GET请求时设置了Content-Type头,该头对GET请求无意义,应该设置Accept头指定接收的manifest类型
  2. 从日志可以看到源站返回的manifest实际是application/vnd.docker.distribution.manifest.v1+prettyjws格式,但PUT时硬编码了v2+json的Content-Type,格式和内容不匹配导致校验失败

修复后的代码

String name = "registry";
String tag = "1";
// get /v2/{name}/manifests/{tag} impl
String url = String.format(fromHost + "/v2/%s/manifests/%s", name, tag);
HttpHeaders httpHeaders = new HttpHeaders();
// GET请求设置Accept头,指定可接收的manifest类型
httpHeaders.set(HttpHeaders.ACCEPT, "application/vnd.docker.distribution.manifest.v2+json, application/vnd.docker.distribution.manifest.v1+prettyjws");
HttpEntity<String> httpEntity = new HttpEntity<>(null, httpHeaders);
ResponseEntity<String> resp = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
// 获取源站返回的真实Content-Type
String contentType = resp.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
System.out.println(contentType);
String manifests = resp.getBody();

// put /v2/{name}/manifests/{tag} impl
httpHeaders.clear();
// 直接使用源站返回的Content-Type,不要硬编码
httpHeaders.set(HttpHeaders.CONTENT_TYPE, contentType);
httpEntity = new HttpEntity<>(manifests, httpHeaders);
resp = restTemplate.exchange(toHost + "/v2/registry/manifests/1",
        HttpMethod.PUT, httpEntity, String.class);
System.out.println(resp);

额外注意事项

  • 不要对获取到的manifest字符串做任何转义、格式化、缩进修改,否则会破坏哈希校验和格式结构
  • 如果manifest包含签名信息,修改内容会导致签名失效,也会触发校验失败
  • 确保PUT请求的Content-Length自动计算正确,不要手动指定错误的长度值

内容的提问来源于stack exchange,提问作者hello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 04:36:00