GoogleContainerTools/jib · error · LayerCountMismatchException
Invalid base image format: manifest contains <n> layers, but
Error message
Invalid base image format: manifest contains <n> layers, but container configuration contains <n> layers
What it means
When loading a base image from a Docker tar archive (cacheDockerImageTar), Jib cross-checks the number of layer files listed in the tar's manifest with the layer count in the container configuration JSON. A mismatch means the tar is malformed or inconsistent, so LayerCountMismatchException is thrown with both counts. This guards against producing a broken image built on inconsistent metadata.
Source
Thrown at jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/LocalBaseImageSteps.java:237
try (InputStream manifestStream =
Files.newInputStream(destination.resolve("manifest.json"))) {
loadManifest =
JsonMapper.builder()
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
.build()
.readValue(manifestStream, DockerManifestEntryTemplate[].class)[0];
}
Path configPath = destination.resolve(loadManifest.getConfig());
ContainerConfigurationTemplate configurationTemplate =
JsonTemplateMapper.readJsonFromFile(configPath, ContainerConfigurationTemplate.class);
// Don't compute the digest of the loaded Java JSON instance.
BlobDescriptor originalConfigDescriptor =
Blobs.from(configPath).writeTo(ByteStreams.nullOutputStream());
List<String> layerFiles = loadManifest.getLayerFiles();
if (configurationTemplate.getLayerCount() != layerFiles.size()) {
throw new LayerCountMismatchException(
"Invalid base image format: manifest contains "
+ layerFiles.size()
+ " layers, but container configuration contains "
+ configurationTemplate.getLayerCount()
+ " layers");
}
buildContext
.getBaseImageLayersCache()
.writeLocalConfig(originalConfigDescriptor.getDigest(), configurationTemplate);
// Check the first layer to see if the layers are compressed already. 'docker save' output
// is uncompressed, but a jib-built tar has compressed layers.
boolean layersAreCompressed =
!layerFiles.isEmpty() && isGzipped(destination.resolve(layerFiles.get(0)));
// Process layer blobs
try (ProgressEventDispatcher progressEventDispatcher =
progressEventDispatcherFactory.create(View on GitHub (pinned to fb949e2676)
Solutions
- Regenerate the tarball: `docker save <image> -o base.tar` from an intact Docker daemon and retry.
- Verify the tar integrity: manifest.json layer count vs config JSON diff_ids; restore missing layer files.
- Use a registry base image reference (e.g. eclipse-temurin:17) instead of a local tar to bypass tar loading.
- Re-pull the base image (`docker pull`) to replace a corrupt local image, then re-save.
- If using a third-party tool to build tars, fix or upgrade that tool to emit matching manifest/config.
Example fix
// before jib.image = "docker://custom-base.tar" // tar with mismatched layers // after // regenerate cleanly docker pull eclipse-temurin:17 docker save eclipse-temurin:17 -o base.tar jib.image = "docker://base.tar"
Defensive patterns
Strategy: validation
Validate before calling
// Inspect tar before handing to jib
int manifestLayers = readManifestLayerCount(baseTar); // from manifest.json
int configLayers = readConfigDiffIdCount(baseTar); // from config JSON rootfs.diff_ids
if (manifestLayers != configLayers) throw new IllegalArgumentException("corrupt base tar"); Type guard
null
Try / catch
try { /* jib build from docker tar */ } catch (LayerCountMismatchException e) { /* regenerate tarball with docker save */ } Prevention
- Always produce base tarballs with `docker save` from an intact image
- Never hand-edit or truncate saved tars; keep layers alongside manifest.json
- Prefer registry base image references over local tar files
- Re-pull images that fail, to replace corrupt local data
When it happens
Trigger: Running `jib build --image=...` with a base image passed via `docker:` tarball (or fromDaemon) whose manifest.json lists a different number of layers than the config JSON's rootfs diff_ids - e.g. manually edited tars, tars produced by non-Docker tools, or partially extracted tars.
Common situations: Building from a `docker save` output that was modified or truncated; third-party image tarball generators producing inconsistent manifests; copying/tarring images incorrectly (missing layer files); older OCI/Docker format variants.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- The input JAR (${jarPath}) is compiled with Java ${jarJavaVe
- Cannot run Jib in offline mode; local Jib cache for base ima
- cannot build for multiple platforms since the base image '%s
- the configured platform (%s/%s) doesn't match the platform (
- Cannot run Jib in offline mode; <imageReference> not found i
AI-assisted analysis of GoogleContainerTools/jib@fb949e2676 (2026-09-06).
Data as JSON: /api/errors/833b2d52df3d91e3.
Report an issue: GitHub.