{"record":{"id":"0697e548bc59f5c2","repo":"GoogleContainerTools/jib","slug":"cannot-find-field-schemaversion-in-manifest","errorCode":null,"errorMessage":"Cannot find field 'schemaVersion' in manifest","messagePattern":"Cannot find field 'schemaVersion' in manifest","errorType":"exception","errorClass":"UnknownManifestFormatException","httpStatus":null,"severity":"error","filePath":"jib-core/src/main/java/com/google/cloud/tools/jib/registry/AbstractManifestPuller.java","lineNumber":140,"sourceCode":"  @Override\n  public String getActionDescription() {\n    return \"pull image manifest for \"\n        + registryEndpointRequestProperties.getServerUrl()\n        + \"/\"\n        + registryEndpointRequestProperties.getImageName()\n        + \":\"\n        + imageQualifier;\n  }\n\n  /**\n   * Instantiates a {@link ManifestTemplate} from a JSON string. This checks the {@code\n   * schemaVersion} field of the JSON to determine which manifest version to use.\n   */\n  private T getManifestTemplateFromJson(String jsonString)\n      throws IOException, UnknownManifestFormatException {\n    ObjectNode node = new ObjectMapper().readValue(jsonString, ObjectNode.class);\n    if (!node.has(\"schemaVersion\")) {\n      throw new UnknownManifestFormatException(\"Cannot find field 'schemaVersion' in manifest\");\n    }\n\n    int schemaVersion = node.get(\"schemaVersion\").asInt(-1);\n    if (schemaVersion == -1) {\n      throw new UnknownManifestFormatException(\"'schemaVersion' field is not an integer\");\n    }\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));","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/GoogleContainerTools/jib/blob/fb949e2676afbbd7dd7a1ef61e20251931325654/jib-core/src/main/java/com/google/cloud/tools/jib/registry/AbstractManifestPuller.java#L122-L158","documentation":"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.","triggerScenarios":"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.","commonSituations":"Registry misconfiguration behind a proxy/mirror that returns custom JSON, an auth page returned instead of the manifest, or a very old/nonconforming registry.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// preflight: confirm registry serves a v2 manifest\n// curl -sI -H \"Accept: application/vnd.docker.distribution.manifest.v2+json\" https://registry.example.com/v2/<image>/manifests/<tag>\n// response JSON must contain a numeric \"schemaVersion\"","typeGuard":null,"tryCatchPattern":"// catch RegistryErrorException and surface registry/proxy diagnostics\ntry {\n    jibContainerBuilder.containerize();\n} catch (RegistryErrorException e) {\n    if (e.getMessage().contains(\"schemaVersion\")) {\n        throw new IllegalStateException(\"Registry did not return a valid v2 manifest — check proxy/registry config\", e);\n    }\n    throw e;\n}","preventionTips":["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."],"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"}