GoogleContainerTools/jib · error · IOException
unable to move: %s to %s; such failures are often caused by
Error message
unable to move: %s to %s; such failures are often caused by interference from antivirus (https://github.com/GoogleContainerTools/jib/issues/3127#issuecomment-796838294), or rarely if the operation is not supported by the file system (for example: special non-local file system)
What it means
CacheStorageWriter.moveIfDoesNotExist() renames a fully written temp file into its final cache location. After retrying the rename 10 times with 15ms pauses (on FileSystemException), a persistent failure throws IOException with a detailed message noting that antivirus interference or unsupported (non-local) file systems are the usual causes. This is the first throw site, after the retry loop exhausts.
Source
Thrown at jib-core/src/main/java/com/google/cloud/tools/jib/cache/CacheStorageWriter.java:146
() -> {
if (Files.exists(destination)) {
// If the file already exists, we skip renaming and use the existing file.
// This happens, e.g., if a new layer happens to have the same content as a
// previously-cached layer or the same layer is being cached concurrently.
return true;
}
Files.move(source, destination);
return Files.exists(destination);
};
// Some Windows users report java.nio.file.AccessDeniedException that we suspect is caused
// by anti-virus programs, like Windows Defender, that open new files for scanning.
// Retry the rename up to 10 times, with 15ms pause between each retry.
if (!Retry.action(rename)
.maximumRetries(10)
.retryOnException(ex -> ex instanceof FileSystemException)
.sleep(15, TimeUnit.MILLISECONDS)
.run()) {
throw new IOException(errorMessage);
}
} catch (IOException ex) {
throw new IOException(errorMessage, ex);
}
}
/**
* Decompresses the file to obtain the diff ID.
*
* @param compressedFile the file containing the compressed contents
* @return the digest of the decompressed file
* @throws IOException if an I/O exception occurs
*/
private static DescriptorDigest getDiffIdByDecompressingFile(Path compressedFile)
throws IOException {
try (InputStream in =
new CompressorStreamFactory(true)View on GitHub (pinned to fb949e2676)
Solutions
- Move the Jib cache to a local disk (set <cache>/jib.cacheDirectory to a local path)
- Add the cache directory to antivirus exclusions
- Close processes holding files in the cache and rebuild
- Re-run the build — transient AV locks often disappear on retry
Example fix
// before (cache on network share) <configuration><cache>/mnt/nfs/jib-cache</cache></configuration> // after <configuration><cache>/home/user/.cache/google-cloud-tools-java/jib</cache></configuration>
Defensive patterns
Strategy: retry
Validate before calling
// Cache must be on a local filesystem supporting atomic rename
if (!Files.getFileStore(cacheDir).supportsFileAttributeView("basic")) {
System.err.println("Jib cache should be on a local disk");
} Try / catch
try {
build();
} catch (IOException e) {
if (e.getMessage().startsWith("unable to move")) {
// antivirus or non-local FS; relocate cache and retry
setCacheDirectory(Path.of(System.getProperty("user.home"), ".cache/jib"));
build();
} else throw e;
} Prevention
- Keep the Jib cache on a local disk, never NFS/SMB
- Add the cache directory to antivirus exclusions
- Avoid cleanup daemons touching the cache during builds
When it happens
Trigger: Files.move/ATOMIC_MOVE from source to destination keeps failing (e.g. FileAccessRetriedException / FileSystemException) through all 10 retries — typically while writeCompressed, writeUncompressed, writeTarLayer, or the layer blob writers move a temp layer file.
Common situations: Antivirus (Windows Defender etc.) locking freshly written files during scan, cache directory on NFS/SMB/network drives lacking atomic rename, another process holding the destination file open.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Unable to create cache directory for project path: ${path} -
- Cannot create FileLayers from non-file, non-directory: ${src
- ${src} is not a parent of ${path}
- NoSuchFileException: <directory>
- NotDirectoryException: <directory>
AI-assisted analysis of GoogleContainerTools/jib@fb949e2676 (2026-09-06).
Data as JSON: /api/errors/260113250f35a028.
Report an issue: GitHub.