GoogleContainerTools/jib · error · UnknownManifestFormatException

'schemaVersion' is 2, but neither 'manifests' nor 'config' e

Error message

'schemaVersion' is 2, but neither 'manifests' nor 'config' exists

What it means

Thrown by AbstractManifestPuller.getManifestTemplateFromJson when schemaVersion is 2 but the JSON contains neither a 'manifests' array (index/list) nor a 'config' object (single manifest), so Jib cannot tell if it is a manifest list, OCI index, or image manifest. It surfaces as UnknownManifestFormatException.

Source

Thrown at jib-core/src/main/java/com/google/cloud/tools/jib/registry/AbstractManifestPuller.java:164

    }

    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));
        }
        if (node.get("config") != null) {
          return manifestTemplateClass.cast(
              JsonTemplateMapper.readJson(jsonString, OciManifestTemplate.class));
        }
        throw new UnknownManifestFormatException(
            "'schemaVersion' is 2, but neither 'manifests' nor 'config' exists");
      }

      String mediaType = mediaTypeNode.asText();
      if (OciManifestTemplate.MANIFEST_MEDIA_TYPE.equals(mediaType)) {
        return manifestTemplateClass.cast(
            JsonTemplateMapper.readJson(jsonString, OciManifestTemplate.class));
      }
      if (V22ManifestTemplate.MANIFEST_MEDIA_TYPE.equals(mediaType)) {
        return manifestTemplateClass.cast(
            JsonTemplateMapper.readJson(jsonString, V22ManifestTemplate.class));
      }
      if (V22ManifestListTemplate.MANIFEST_MEDIA_TYPE.equals(mediaType)) {
        return manifestTemplateClass.cast(
            JsonTemplateMapper.readJson(jsonString, V22ManifestListTemplate.class));
      }
      if (OciIndexTemplate.MEDIA_TYPE.equals(mediaType)) {
        return manifestTemplateClass.cast(

View on GitHub (pinned to fb949e2676)

Solutions

  1. Check the raw manifest JSON; ensure a schemaVersion:2 image manifest has a 'config' object, or an index has a 'manifests' array.
  2. Fix the registry/proxy serving the malformed manifest or point Jib at the canonical registry.
  3. If constructing manifests for tests, base them on the Docker/OCI v2 schema with all required fields.

Example fix

// before
{"schemaVersion": 2, "blobs": [...], "layers": [...]}
// after
{"schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "config": {...}, "layers": [...]}
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: schemaVersion 2 manifests must have config or manifests
// curl -s <manifest-url> | jq 'has("config") or has("manifests")'
// expect: true

Try / catch

// catch and diagnose incomplete schemaVersion-2 manifests
try {
    jibContainerBuilder.containerize();
} catch (RegistryErrorException e) {
    if (e.getMessage().contains("neither 'manifests' nor 'config'")) {
        throw new IllegalStateException("Registry returned an incomplete schemaVersion-2 manifest", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A schemaVersion:2 manifest missing both 'manifests' and 'config' fields — typically a truncated, hand-edited, or nonstandard registry response.

Common situations: Custom registries that emit schemaVersion 2 with a nonconforming payload, proxies mangling the manifest, or test fixtures copied incorrectly.

Related errors


AI-assisted analysis of GoogleContainerTools/jib@fb949e2676 (2026-09-06). Data as JSON: /api/errors/c98891a42d89dac0. Report an issue: GitHub.