GoogleContainerTools/jib · error · LayerCountMismatchException

Mismatch between image manifest and container configuration

Error message

Mismatch between image manifest and container configuration

What it means

Jib keeps manifest layers and container-config diff IDs index-aligned: layer i's diff ID is diffIds[i]. toImage throws LayerCountMismatchException when their counts differ, because the pairing would be ambiguous.

Source

Thrown at jib-core/src/main/java/com/google/cloud/tools/jib/image/json/JsonToImageTranslator.java:126

      ContainerConfigurationTemplate containerConfigurationTemplate)
      throws LayerCountMismatchException, LayerPropertyNotFoundException,
          BadContainerConfigurationFormatException {
    List<ReferenceNoDiffIdLayer> layers = new ArrayList<>();
    for (BuildableManifestTemplate.ContentDescriptorTemplate layerObjectTemplate :
        manifestTemplate.getLayers()) {
      if (layerObjectTemplate.getDigest() == null) {
        throw new IllegalArgumentException(
            "All layers in the manifest template must have digest set");
      }

      layers.add(
          new ReferenceNoDiffIdLayer(
              new BlobDescriptor(layerObjectTemplate.getSize(), layerObjectTemplate.getDigest())));
    }

    List<DescriptorDigest> diffIds = containerConfigurationTemplate.getDiffIds();
    if (layers.size() != diffIds.size()) {
      throw new LayerCountMismatchException(
          "Mismatch between image manifest and container configuration");
    }

    Image.Builder imageBuilder = Image.builder(manifestTemplate.getClass());

    for (int layerIndex = 0; layerIndex < layers.size(); layerIndex++) {
      ReferenceNoDiffIdLayer noDiffIdLayer = layers.get(layerIndex);
      DescriptorDigest diffId = diffIds.get(layerIndex);

      imageBuilder.addLayer(new ReferenceLayer(noDiffIdLayer.getBlobDescriptor(), diffId));
    }

    configureBuilderWithContainerConfiguration(imageBuilder, containerConfigurationTemplate);
    return imageBuilder.build();
  }

  private static void configureBuilderWithContainerConfiguration(
      Image.Builder imageBuilder, ContainerConfigurationTemplate containerConfigurationTemplate)

View on GitHub (pinned to fb949e2676)

Solutions

  1. Fetch the manifest and container configuration from the same image reference so their layer counts match
  2. Verify manifest.getLayers().size() equals containerConfig.getDiffIds().size() before calling toImage
  3. Clear stale cached config/manifest pairs and re-pull both from the registry

Example fix

// before
Image image = JsonToImageTranslator.toImage(manifestA, configB); // from different tags
// after
if (manifestA.getLayers().size() != configB.getDiffIds().size()) {
  throw new IllegalStateException("manifest/config mismatch; re-fetch both from same reference");
}
Image image = JsonToImageTranslator.toImage(manifestA, configA);
Defensive patterns

Strategy: validation

Validate before calling

if (manifestTemplate.getLayers().size() != containerConfigurationTemplate.getDiffIds().size())
  throw new IllegalStateException("manifest layer count != config diff ID count; refetch both from same image");

Try / catch

try { JsonToImageTranslator.toImage(manifest, config); } catch (LayerCountMismatchException e) { /* re-pull manifest+config from the same tag */ }

Prevention

When it happens

Trigger: Calling JsonToImageTranslator.toImage with a manifest and a container configuration that come from different images, or with a truncated/corrupted config whose diffIds list length differs from the manifest layer count.

Common situations: Mixing manifest and config blobs fetched from different registries/tags; a retagged image whose config wasn't updated; hand-crafted test fixtures with mismatched layer counts; pulling a stale cached config after the image was pushed anew.

Related errors


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