elastic/elasticsearch · error · UncheckedIOException

Failed to patch archive

Error message

Failed to patch archive

What it means

FilteringJarTransform throws an UncheckedIOException wrapping any IOException raised while reading the input jar, copying filtered entries, or finalizing the output jar. The transform reads each zip entry, skips entries matching any exclude glob, and streams the rest to a new jar; an I/O failure (corrupt input, disk full, interrupted stream) aborts with this generic message.

Source

Thrown at build-tools/src/main/java/org/elasticsearch/gradle/transform/FilteringJarTransform.java:73

        try (
            ZipFile input = new ZipFile(original);
            ZipOutputStream output = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(transformed)))
        ) {
            Enumeration<? extends ZipEntry> entries = input.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = entries.nextElement();
                if (excludes.stream().noneMatch(e -> e.matches(Path.of(entry.getName())))) {
                    output.putNextEntry(entry);
                    input.getInputStream(entry).transferTo(output);
                    output.closeEntry();
                }
            }

            output.flush();
            output.finish();
        } catch (IOException e) {
            throw new UncheckedIOException("Failed to patch archive", e);
        }
    }

    private List<PathMatcher> createMatchers(List<String> patterns) {
        return patterns.stream().map(p -> FileSystems.getDefault().getPathMatcher("glob:" + p)).toList();
    }

    public static void registerTransform(DependencyHandler dependencyHandler, Action<Parameters> config) {
        dependencyHandler.registerTransform(FilteringJarTransform.class, spec -> {
            spec.getFrom().attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.JAR_TYPE);
            spec.getTo().attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, FILTERED_JAR_TYPE);
            config.execute(spec.getParameters());
        });
    }

    public abstract static class Parameters implements TransformParameters, Serializable {
        private List<String> excludes = new ArrayList<>();

View on GitHub (pinned to db6a809a66)

Solutions

  1. Run `./gradlew --refresh-dependencies` to re-download potentially corrupt dependency jars.
  2. Clear the transform's output cache (`rm -rf` the relevant `.gradle/caches/transforms-*` dir or run `--rerun-tasks`).
  3. Check disk space and permissions on the Gradle user home and project build dirs.
  4. Inspect the wrapped IOException's cause for the specific entry/path that failed; isolate whether it's one input jar or all.
Defensive patterns

Strategy: retry

Try / catch

try {
  transform();
} catch (UncheckedIOException e) {
  if (e.getMessage().contains("Failed to patch archive")) {
    // purge the corrupt input from cache and retry once
    cleanTransformCache(inputArtifact);
  }
  throw e;
}

Prevention

When it happens

Trigger: The transform is registered to produce a 'filtered jar' artifact type from a standard jar. It fails if the input jar is corrupt/truncated, an entry can't be read, the output path isn't writable, or the process is interrupted mid-copy.

Common situations: A cached/downloaded dependency jar is partially downloaded (network blip); a snapshot jar overwritten mid-transform by another process; disk full in the Gradle build cache; a glob pattern whose PathMatcher throws; concurrent builds racing on the same transform output.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/2bdfa9b74c430159. Report an issue: GitHub.