elastic/elasticsearch · error · IllegalArgumentException

error patching [%s]: the jar does not contain [%s]

Error message

error patching [%s]: the jar does not contain [%s]

What it means

Thrown by Utils.patchJar after iterating all JAR entries: the classPatchers map (built from the requested PatcherInfo collection) still has leftover entries, meaning the input JAR did not contain class entries matching the patcher jar-entry names. The patcher targets specific class paths inside the JAR (e.g. 'com/foo/Bar.class') and cannot proceed if those entries are absent, because patching nothing would silently produce an unpatched JAR.

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/dependencies/patches/Utils.java:153

            throw new RuntimeException(ex);
        }

        if (mismatchedClasses.isEmpty() == false) {
            throw new IllegalArgumentException(
                String.format(
                    Locale.ROOT,
                    """
                        Error patching JAR [%s]: SHA256 digest mismatch (%s). This JAR was updated to a version that contains different \
                        classes, for which this patcher was not designed. Please check if the patcher still \
                        applies correctly, and update the SHA256 digest(s).""",
                    inputFile.getName(),
                    mismatchedClasses.stream().map(MismatchInfo::toString).collect(Collectors.joining())
                )
            );
        }

        if (classPatchers.isEmpty() == false) {
            throw new IllegalArgumentException(
                String.format(
                    Locale.ROOT,
                    "error patching [%s]: the jar does not contain [%s]",
                    inputFile.getName(),
                    String.join(", ", classPatchers.keySet())
                )
            );
        }
    }
}

View on GitHub (pinned to db6a809a66)

Solutions

  1. Open the input JAR with 'jar tf <file>.jar | grep <className>' and find the actual entry name for the class you intend to patch.
  2. Update the PatcherInfo jarEntryName in the patch configuration (e.g. the JarRelocation/Patches block in build-conventions or the module's build.gradle) to match the real entry path.
  3. If the class was genuinely removed in the new dependency version, remove the now-obsolete PatcherInfo entry and verify the patch is no longer needed.
  4. Pin the dependency to the version the patcher was written for until the patcher is updated.

Example fix

// before: patcher references an entry that no longer exists
new PatcherInfo("com/fasterxml/jackson/databind/ObjectMapper.class", sha, visitor)

// after: confirm actual entry name in the upgraded JAR and update
// run: jar tf jackson-databind-2.17.0.jar | grep ObjectMapper
new PatcherInfo("com/fasterxml/jackson/databind/ObjectMapper.class", newSha, visitor)
Defensive patterns

Strategy: validation

Validate before calling

// Before calling Utils.patchJar, confirm every patcher entry exists in the JAR
import java.util.jar.JarFile;
import java.util.HashSet;
import java.util.Set;

void verifyPatchTargets(File inputJar, Collection<PatcherInfo> patchers) throws IOException {
    Set<String> entries;
    try (JarFile jf = new JarFile(inputJar)) {
        entries = new HashSet<>(jf.stream().map(JarEntry::getName).toList());
    }
    var missing = patchers.stream()
        .map(PatcherInfo::jarEntryName)
        .filter(e -> !entries.contains(e))
        .toList();
    if (!missing.isEmpty()) {
        throw new IllegalStateException(
            "JAR " + inputJar + " is missing patch targets: " + missing
            + ". Available entries containing the class name: "
            + entries.stream().filter(e -> e.contains(missing.get(0).replace('/', '.').replace(".class",""))).toList()
        );
    }
}
// call: verifyPatchTargets(inputFile, patchers);

Prevention

When it happens

Trigger: A dependency JAR is upgraded to a version where the target class was renamed, moved to a different package, or removed entirely; or a PatcherInfo was configured with a typo'd jarEntryName that does not correspond to any entry in the JAR being patched.

Common situations: Bumping a third-party dependency version (e.g. jackson, lucene) in build-conventions or a module's build.gradle without updating the corresponding patch definitions; the upstream library refactored or deleted the patched class. Less commonly, a patcher was authored against a wrong or typo'd entry name from the start.

Related errors


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