GoogleContainerTools/jib · error · UnknownManifestFormatException
Cannot find field 'schemaVersion' in manifest
Error message
Cannot find field 'schemaVersion' in manifest
What it means
Thrown by AbstractManifestPuller.getManifestTemplateFromJson when the manifest JSON returned by the registry lacks a 'schemaVersion' field. Jib uses that field to decide between Docker V2.1/V2.2 and OCI manifest formats, so a manifest without it cannot be interpreted. It surfaces as UnknownManifestFormatException.
Source
Thrown at jib-core/src/main/java/com/google/cloud/tools/jib/registry/AbstractManifestPuller.java:140
@Override
public String getActionDescription() {
return "pull image manifest for "
+ registryEndpointRequestProperties.getServerUrl()
+ "/"
+ registryEndpointRequestProperties.getImageName()
+ ":"
+ imageQualifier;
}
/**
* Instantiates a {@link ManifestTemplate} from a JSON string. This checks the {@code
* schemaVersion} field of the JSON to determine which manifest version to use.
*/
private T getManifestTemplateFromJson(String jsonString)
throws IOException, UnknownManifestFormatException {
ObjectNode node = new ObjectMapper().readValue(jsonString, ObjectNode.class);
if (!node.has("schemaVersion")) {
throw new UnknownManifestFormatException("Cannot find field 'schemaVersion' in manifest");
}
int schemaVersion = node.get("schemaVersion").asInt(-1);
if (schemaVersion == -1) {
throw new UnknownManifestFormatException("'schemaVersion' field is not an integer");
}
if (schemaVersion == 1) {
return manifestTemplateClass.cast(
JsonTemplateMapper.readJson(jsonString, V21ManifestTemplate.class));
}
if (schemaVersion == 2) {
// 'schemaVersion' of 2 can be either Docker V2.2 or OCI.
JsonNode mediaTypeNode = node.get("mediaType");
if (mediaTypeNode == null) { // not Docker, hence OCI
if (node.get("manifests") != null) {
return manifestTemplateClass.cast(
JsonTemplateMapper.readJson(jsonString, OciIndexTemplate.class));View on GitHub (pinned to fb949e2676)
Solutions
- Verify the registry URL points to a real Docker Registry v2 endpoint, not a proxy or UI page.
- Inspect the raw response with curl (Accept: application/vnd.docker.distribution.manifest.v2+json) to see what the server returns.
- Check proxy/mirror configuration so it forwards registry responses unmodified.
- If the registry is third-party, confirm it supports the Docker Registry HTTP API v2.
Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: confirm registry serves a v2 manifest // curl -sI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" https://registry.example.com/v2/<image>/manifests/<tag> // response JSON must contain a numeric "schemaVersion"
Try / catch
// catch RegistryErrorException and surface registry/proxy diagnostics
try {
jibContainerBuilder.containerize();
} catch (RegistryErrorException e) {
if (e.getMessage().contains("schemaVersion")) {
throw new IllegalStateException("Registry did not return a valid v2 manifest — check proxy/registry config", e);
}
throw e;
} Prevention
- Point image references at registries implementing the Docker Registry HTTP API v2.
- Check that proxies/mirrors forward registry responses unmodified.
- Verify with curl that /v2/ endpoints return manifest JSON, not HTML or auth pages.
When it happens
Trigger: Pulling a manifest from an endpoint that returns non-standard JSON (e.g. an HTML error page, an API response, or a registry proxy stripping fields) while Jib expects a Docker/OCI manifest.
Common situations: Registry misconfiguration behind a proxy/mirror that returns custom JSON, an auth page returned instead of the manifest, or a very old/nonconforming registry.
Related errors
- 'schemaVersion' field is not an integer
- 'schemaVersion' is 2, but neither 'manifests' nor 'config' e
- Unknown schemaVersion: + schemaVersion + " - only 1 and 2 ar
- Unknown mediaType: + mediaType
- Dependency required by the JAR (as specified in `Class-Path`
AI-assisted analysis of GoogleContainerTools/jib@fb949e2676 (2026-09-06).
Data as JSON: /api/errors/0697e548bc59f5c2.
Report an issue: GitHub.