GoogleContainerTools/jib · error · IOException
Cannot run Jib in offline mode; local Jib cache for base ima
Error message
Cannot run Jib in offline mode; local Jib cache for base image is missing image layer <layerDigest>. Rerun Jib in online mode with "-Djib.alwaysCacheBaseImage=true" to re-download the base image layers.
What it means
In offline mode Jib cannot download base image layers. When a base image layer digest is not present in the local Jib cache and the build is offline, ObtainBaseImageLayerStep.call throws IOException telling the user to rerun online (optionally with -Djib.alwaysCacheBaseImage=true) so layers are persisted in the project cache. This prevents builds from silently producing images missing layers.
Source
Thrown at jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/ObtainBaseImageLayerStep.java:129
StateInTarget stateInTarget = blobExistenceChecker.check(layerDigest);
if (stateInTarget == StateInTarget.EXISTING) {
eventHandlers.dispatch(
LogEvent.info(
"Skipping pull; BLOB already exists on target registry : "
+ layer.getBlobDescriptor()));
return new PreparedLayer.Builder(layer).setStateInTarget(stateInTarget).build();
}
Cache cache = buildContext.getBaseImageLayersCache();
// Checks if the layer already exists in the cache.
Optional<CachedLayer> optionalCachedLayer = cache.retrieve(layerDigest);
if (optionalCachedLayer.isPresent()) {
CachedLayer cachedLayer = optionalCachedLayer.get();
return new PreparedLayer.Builder(cachedLayer).setStateInTarget(stateInTarget).build();
} else if (buildContext.isOffline()) {
throw new IOException(
"Cannot run Jib in offline mode; local Jib cache for base image is missing image layer "
+ layerDigest
+ ". Rerun Jib in online mode with \"-Djib.alwaysCacheBaseImage=true\" to "
+ "re-download the base image layers.");
}
try (ThrottledProgressEventDispatcherWrapper progressEventDispatcherWrapper =
new ThrottledProgressEventDispatcherWrapper(
progressEventDispatcher.newChildProducer(),
"pulling base image layer " + layerDigest)) {
CachedLayer cachedLayer =
cache.writeCompressedLayer(
Verify.verifyNotNull(registryClient)
.pullBlob(
layerDigest,
progressEventDispatcherWrapper::setProgressTarget,
progressEventDispatcherWrapper::dispatchProgress));
return new PreparedLayer.Builder(cachedLayer).setStateInTarget(stateInTarget).build();View on GitHub (pinned to fb949e2676)
Solutions
- Rerun once with network access: remove --offline / set jib.offline=false, and add -Djib.alwaysCacheBaseImage=true to populate the persistent cache, then go offline again.
- Pin/use a base image whose layers are already in the local cache (previously downloaded).
- Warm the cache on a connected machine and copy the Jib cache directory to the offline environment.
- If available, build from a Docker daemon image (docker daemonizer or docker:// tar path) whose layers don't need the Jib cache.
- Restore the base image layers by re-running the same build online with the same base image tag/digest.
Example fix
// before (CI, offline runner) ./gradlew jibBuild --offline // after ./gradlew jibBuild -Djib.alwaysCacheBaseImage=true // once, online, to warm cache // subsequent offline builds ./gradlew jibBuild --offline
Defensive patterns
Strategy: retry
Validate before calling
// Check cache before going offline
for (String digest : baseImageLayerDigests) {
if (cache.retrieve(digest).isEmpty()) throw new IllegalStateException("warm cache online first: " + digest);
} Type guard
null
Try / catch
try { /* offline build */ } catch (IOException e) {
if (e.getMessage().contains("offline mode")) { /* rerun online with -Djib.alwaysCacheBaseImage=true, then retry offline */ }
else throw e;
} Prevention
- Warm the Jib cache with -Djib.alwaysCacheBaseImage=true before network-restricted CI runs
- Pin base image tags/digests so cached layers stay valid
- Avoid clearing the Jib cache on offline runners
- Pre-copy the cache directory into air-gapped environments
When it happens
Trigger: Running with `--offline=true` (or jib.offline=true) while the local cache lacks a layer of the base image - e.g. the base image digest changed upstream, the cache was cleared, or a pinned digest was never downloaded on this machine.
Common situations: CI jobs run in network-isolated sandboxes after cache eviction; air-gapped environments switching base image tags so the cached layers no longer match; using `docker://` metadata flows expecting the Jib cache (not the Docker daemon cache); first build on a new machine with --offline.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Cannot run Jib in offline mode; <imageReference> not found i
- The input JAR (${jarPath}) is compiled with Java ${jarJavaVe
- Unable to create cache directory for project path: ${path} -
- Invalid base image format: manifest contains <n> layers, but
- cannot build for multiple platforms since the base image '%s
AI-assisted analysis of GoogleContainerTools/jib@fb949e2676 (2026-09-06).
Data as JSON: /api/errors/23d6c094136c2c3c.
Report an issue: GitHub.