elastic/elasticsearch · error · GradleException
failed writing tar file [${tarFile}]
Error message
failed writing tar file [${tarFile}] What it means
Thrown by SymbolicLinkPreservingTar's copy action when an IOException escapes the top-level try-with-resources that opens and writes the tar archive output stream. This wraps failures in creating/closing the compressed stream (gzip/bzip2/uncompressed) or any unhandled error during stream.process(...). It is the outer guard; per-entry failures are reported separately by error 178.
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/SymbolicLinkPreservingTar.java:81
final Provider<RegularFile> tarFile,
final ArchiveOutputStreamFactory compressor,
final boolean isPreserveFileTimestamps
) {
this.tarFile = tarFile;
this.compressor = compressor;
this.isPreserveFileTimestamps = isPreserveFileTimestamps;
}
@Override
public WorkResult execute(final CopyActionProcessingStream stream) {
try (
OutputStream out = compressor.createArchiveOutputStream(tarFile.get().getAsFile());
TarArchiveOutputStream tar = new TarArchiveOutputStream(out)
) {
tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
stream.process(new SymbolicLinkPreservingTarStreamAction(tar));
} catch (final IOException e) {
throw new GradleException("failed writing tar file [" + tarFile + "]", e);
}
return WorkResults.didWork(true);
}
private class SymbolicLinkPreservingTarStreamAction implements CopyActionProcessingStreamAction {
private final TarArchiveOutputStream tar;
/*
* When Gradle walks the file tree, it will follow symbolic links. This means that if there is a symbolic link to a directory
* in the source file tree, we could otherwise end up duplicating the entries below that directory in the resulting tar archive.
* To avoid this, we track which symbolic links we have visited, and skip files that are children of symbolic links that we have
* already visited.
*/
private final Set<File> visitedSymbolicLinks = new HashSet<>();
SymbolicLinkPreservingTarStreamAction(final TarArchiveOutputStream tar) {View on GitHub (pinned to db6a809a66)
Solutions
- Check the archiveFile target path (shown as tarFile in the message): ensure its parent directory exists and is writable.
- Free disk space on the target volume and retry.
- On Windows, ensure no other process (antivirus, explorer, archiver) holds the output file.
- Verify the task's compression setting matches a supported codec (GZIP/BZIP2/none).
- If the failure originates from a single entry, look for error 178 which carries the per-entry 'could not add' detail.
Defensive patterns
Strategy: try-catch
Validate before calling
import java.nio.file.*;
import java.io.File;
File target = archiveFile.getAsFile().get();
File parent = target.getParentFile();
if (parent == null || !parent.exists())
throw new IllegalArgumentException("tar output parent missing: " + parent);
if (!parent.canWrite())
throw new IllegalArgumentException("tar output dir not writable: " + parent);
if (target.exists() && !target.isFile())
throw new IllegalArgumentException("tar target is not a regular file: " + target);
if (target.exists() && !target.canWrite())
throw new IllegalArgumentException("existing tar target not writable: " + target); Try / catch
try (OutputStream out = compressor.createArchiveOutputStream(tarFile.get().getAsFile());
TarArchiveOutputStream tar = new TarArchiveOutputStream(out)) {
tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
stream.process(new SymbolicLinkPreservingTarStreamAction(tar));
} catch (final IOException e) {
throw new GradleException("failed writing tar file [" + tarFile + "]", e);
} Prevention
- Ensure the archive output directory exists and is writable before running the task.
- Free disk space on the target volume; tars can be large.
- On Windows, ensure no process holds the output file.
When it happens
Trigger: The execute(CopyActionProcessingStream) method opens compressor.createArchiveOutputStream(tarFile) and a TarArchiveOutputStream over it; any IOException during opening, writing headers via stream.process, or closing the streams is caught by catch (final IOException e) and rethrown.
Common situations: The archiveFile output path is not writable or its parent directory does not exist; disk full while writing the tar; the output file is locked by another process (Windows); permissions denied on the target directory; the compression codec threw during stream construction.
Related errors
- could not add [${details}] to tar file [${tarFile}]
- Cannot load VersionPropertiesBuildService
- Cannot resolve minimum compiler version via VersionPropertie
- unable to read the git revision
- Cannot read ${f} to check for duplicate license headers
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/b11a8ac3149d07f8.
Report an issue: GitHub.