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
- Configure Jib to use a manifest format the registry supports (e.g., Docker V2.2 instead of OCI) via the image format/build setting
- Upgrade the target registry to a version supporting Schema 2 / OCI manifests
- Verify the registry is not behind a proxy that strips or rejects the manifest media type
- 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
- Check the target registry supports Schema 2 / OCI before enabling those formats
- Upgrade legacy registries
- Test pushes to staging registries with the same version
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
- Cannot build to a container registry in offline mode
- Invalid container configuration in Docker V2.2/OCI manifest:
- insecure HTTP connection not allowed: + url
- The pulled BLOB has digest '${receivedDigest}', but the requ
- Did not get token in authentication response from ${authenti
AI-assisted analysis of GoogleContainerTools/jib@fb949e2676 (2026-09-06).
Data as JSON: /api/errors/d2599f90eb005c1b.
Report an issue: GitHub.