GoogleContainerTools/jib · error · RegistryErrorException

Registry may not support pushing OCI Manifest or Docker Imag

Error message

Registry may not support pushing OCI Manifest or Docker Image Manifest Version 2, Schema 2

What it means

ManifestPusher converts certain registry HTTP error responses into a RegistryErrorException explaining that the registry likely does not support OCI manifests or Docker Image Manifest Version 2, Schema 2. When the registry responds with a MANIFEST_INVALID or TAG_INVALID error code, Jib surfaces this hint because those codes commonly indicate schema-version incompatibility rather than a malformed manifest.

Source

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

    // docker registry 2.0 and 2.1 returns:
    //   400 Bad Request
    //   {"errors":[{"code":"TAG_INVALID","message":"manifest tag did not match URI"}]}
    // docker registry:2.2 returns:
    //   400 Bad Request
    //   {"errors":[{"code":"MANIFEST_INVALID","message":"manifest invalid","detail":{}}]}
    // quay.io returns:
    //   415 UNSUPPORTED MEDIA TYPE
    //   {"errors":[{"code":"MANIFEST_INVALID","detail":
    //   {"message":"manifest schema version not supported"},"message":"manifest invalid"}]}

    if (responseException.getStatusCode() != HttpStatus.SC_BAD_REQUEST
        && responseException.getStatusCode() != HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE) {
      throw responseException;
    }

    ErrorCodes errorCode = ErrorResponseUtil.getErrorCode(responseException);
    if (errorCode == ErrorCodes.MANIFEST_INVALID || errorCode == ErrorCodes.TAG_INVALID) {
      throw new RegistryErrorExceptionBuilder(getActionDescription(), responseException)
          .addReason(
              "Registry may not support pushing OCI Manifest or "
                  + "Docker Image Manifest Version 2, Schema 2")
          .build();
    }
    // rethrow: unhandled error response code.
    throw responseException;
  }

  @Override
  public DescriptorDigest handleResponse(Response response) throws IOException {
    // Checks if the image digest is as expected.
    DescriptorDigest expectedDigest = Digests.computeJsonDigest(manifestTemplate);

    List<String> receivedDigests = response.getHeader(RESPONSE_DIGEST_HEADER);
    if (receivedDigests.size() == 1) {
      try {
        DescriptorDigest receivedDigest = DescriptorDigest.fromDigest(receivedDigests.get(0));

View on GitHub (pinned to fb949e2676)

Solutions

  1. Configure Jib to use a manifest format the registry supports (e.g., Docker V2.2 instead of OCI) via the image format/build setting
  2. Upgrade the target registry to a version supporting Schema 2 / OCI manifests
  3. Verify the registry is not behind a proxy that strips or rejects the manifest media type
  4. Inspect the full registry error response for the underlying reason

Example fix

// before: OCI format pushed to legacy registry
jibContainerBuilder.containerize(Containerizer.to(RegistryImage.name("legacy.example.com/app")).setFormat(ImageFormat.OCI));
// after: use Docker manifest format
jibContainerBuilder.containerize(Containerizer.to(RegistryImage.name("legacy.example.com/app")).setFormat(ImageFormat.Docker));
Defensive patterns

Strategy: fallback

Validate before calling

// check registry capability before pushing with OCI format
curl -s https://registry.example.com/v2/ | head  // confirm v2 API reachable

Try / catch

try { client.pushManifest(manifest, tag); } catch (RegistryErrorException e) { // fall back to Docker V2.2 format
  pushAsDockerV22(); }

Prevention

When it happens

Trigger: Pushing a manifest via ManifestPusher.handleHttpResponseException where the registry's error response carries error code MANIFEST_INVALID or TAG_INVALID (and the original status was UNAUTHORIZED, FORBIDDEN, or UNSUPPORTED_MEDIA_TYPE filtered upstream).

Common situations: Pushing to an old or minimal registry (e.g., a legacy Docker registry or an old Quay/portus version) that only supports Schema 1 manifests; pushing OCI image index/manifest to a registry that only accepts Docker v2; registry misconfiguration disabling media type application/vnd.docker.distribution.manifest.v2+json.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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