GoogleContainerTools/jib · error · UnknownManifestFormatException

'schemaVersion' field is not an integer

Error message

'schemaVersion' field is not an integer

What it means

Thrown by AbstractManifestPuller.getManifestTemplateFromJson when the manifest's 'schemaVersion' field exists but is not an integer (asInt(-1) returns the -1 sentinel). Jib branches on the integer schema version (1 or 2), so a string/boolean/null value makes the manifest unclassifiable. It surfaces as UnknownManifestFormatException.

Source

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

        + registryEndpointRequestProperties.getImageName()
        + ":"
        + imageQualifier;
  }

  /**
   * Instantiates a {@link ManifestTemplate} from a JSON string. This checks the {@code
   * schemaVersion} field of the JSON to determine which manifest version to use.
   */
  private T getManifestTemplateFromJson(String jsonString)
      throws IOException, UnknownManifestFormatException {
    ObjectNode node = new ObjectMapper().readValue(jsonString, ObjectNode.class);
    if (!node.has("schemaVersion")) {
      throw new UnknownManifestFormatException("Cannot find field 'schemaVersion' in manifest");
    }

    int schemaVersion = node.get("schemaVersion").asInt(-1);
    if (schemaVersion == -1) {
      throw new UnknownManifestFormatException("'schemaVersion' field is not an integer");
    }

    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));
        }

View on GitHub (pinned to fb949e2676)

Solutions

  1. Inspect the manifest JSON returned by the registry and confirm schemaVersion is a numeric value (e.g. 2).
  2. Fix or replace the registry/proxy that is emitting a non-integer schemaVersion.
  3. If using a mock registry in tests, update its fixture manifests to include an integer schemaVersion.

Example fix

// before
{"schemaVersion": "2", ...}
// after
{"schemaVersion": 2, ...}
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: schemaVersion must be an integer
// curl -s https://registry.example.com/v2/<image>/manifests/<tag> | jq '.schemaVersion | type'
// expect: "number"

Try / catch

// catch and diagnose nonconforming registry responses
try {
    jibContainerBuilder.containerize();
} catch (RegistryErrorException e) {
    if (e.getMessage().contains("not an integer")) {
        throw new IllegalStateException("Registry returned a manifest with non-integer schemaVersion — registry or proxy is nonconforming", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A registry returns a manifest where 'schemaVersion' is a string like "2" or "latest", a JSON object, or null rather than a JSON number.

Common situations: Custom or misbehaving registry implementations, middleware rewriting manifest JSON, or hand-crafted mock registries used in CI.

Related errors


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