{"record":{"id":"c98891a42d89dac0","repo":"GoogleContainerTools/jib","slug":"schemaversion-is-2-but-neither-manifests-nor","errorCode":null,"errorMessage":"'schemaVersion' is 2, but neither 'manifests' nor 'config' exists","messagePattern":"'schemaVersion' is 2, but neither 'manifests' nor 'config' exists","errorType":"exception","errorClass":"UnknownManifestFormatException","httpStatus":null,"severity":"error","filePath":"jib-core/src/main/java/com/google/cloud/tools/jib/registry/AbstractManifestPuller.java","lineNumber":164,"sourceCode":"    }\n\n    if (schemaVersion == 1) {\n      return manifestTemplateClass.cast(\n          JsonTemplateMapper.readJson(jsonString, V21ManifestTemplate.class));\n    }\n    if (schemaVersion == 2) {\n      // 'schemaVersion' of 2 can be either Docker V2.2 or OCI.\n      JsonNode mediaTypeNode = node.get(\"mediaType\");\n      if (mediaTypeNode == null) { // not Docker, hence OCI\n        if (node.get(\"manifests\") != null) {\n          return manifestTemplateClass.cast(\n              JsonTemplateMapper.readJson(jsonString, OciIndexTemplate.class));\n        }\n        if (node.get(\"config\") != null) {\n          return manifestTemplateClass.cast(\n              JsonTemplateMapper.readJson(jsonString, OciManifestTemplate.class));\n        }\n        throw new UnknownManifestFormatException(\n            \"'schemaVersion' is 2, but neither 'manifests' nor 'config' exists\");\n      }\n\n      String mediaType = mediaTypeNode.asText();\n      if (OciManifestTemplate.MANIFEST_MEDIA_TYPE.equals(mediaType)) {\n        return manifestTemplateClass.cast(\n            JsonTemplateMapper.readJson(jsonString, OciManifestTemplate.class));\n      }\n      if (V22ManifestTemplate.MANIFEST_MEDIA_TYPE.equals(mediaType)) {\n        return manifestTemplateClass.cast(\n            JsonTemplateMapper.readJson(jsonString, V22ManifestTemplate.class));\n      }\n      if (V22ManifestListTemplate.MANIFEST_MEDIA_TYPE.equals(mediaType)) {\n        return manifestTemplateClass.cast(\n            JsonTemplateMapper.readJson(jsonString, V22ManifestListTemplate.class));\n      }\n      if (OciIndexTemplate.MEDIA_TYPE.equals(mediaType)) {\n        return manifestTemplateClass.cast(","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/GoogleContainerTools/jib/blob/fb949e2676afbbd7dd7a1ef61e20251931325654/jib-core/src/main/java/com/google/cloud/tools/jib/registry/AbstractManifestPuller.java#L146-L182","documentation":"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.","triggerScenarios":"A schemaVersion:2 manifest missing both 'manifests' and 'config' fields — typically a truncated, hand-edited, or nonstandard registry response.","commonSituations":"Custom registries that emit schemaVersion 2 with a nonconforming payload, proxies mangling the manifest, or test fixtures copied incorrectly.","solutions":["Check the raw manifest JSON; ensure a schemaVersion:2 image manifest has a 'config' object, or an index has a 'manifests' array.","Fix the registry/proxy serving the malformed manifest or point Jib at the canonical registry.","If constructing manifests for tests, base them on the Docker/OCI v2 schema with all required fields."],"exampleFix":"// before\n{\"schemaVersion\": 2, \"blobs\": [...], \"layers\": [...]}\n// after\n{\"schemaVersion\": 2, \"mediaType\": \"application/vnd.docker.distribution.manifest.v2+json\", \"config\": {...}, \"layers\": [...]}","handlingStrategy":"try-catch","validationCode":"// preflight: schemaVersion 2 manifests must have config or manifests\n// curl -s <manifest-url> | jq 'has(\"config\") or has(\"manifests\")'\n// expect: true","typeGuard":null,"tryCatchPattern":"// catch and diagnose incomplete schemaVersion-2 manifests\ntry {\n    jibContainerBuilder.containerize();\n} catch (RegistryErrorException e) {\n    if (e.getMessage().contains(\"neither 'manifests' nor 'config'\")) {\n        throw new IllegalStateException(\"Registry returned an incomplete schemaVersion-2 manifest\", e);\n    }\n    throw e;\n}","preventionTips":["Verify your registry serves complete manifests including 'config' or 'manifests'.","Avoid proxies that truncate or transform manifest payloads.","For test registries, generate manifests from the official Docker/OCI schema."],"tags":["docker-registry","manifest","registry-protocol"],"backgroundTag":"unexpected-response-shape","analyzedSha":"fb949e2676afbbd7dd7a1ef61e20251931325654","analyzedAt":"2026-09-06T14:04:09.491Z","contentChangedAt":"2026-09-06T14:04:09.491Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}