apache/kafka · error · MojoExecutionException

Failed to check internal API usage: {}

Error message

Failed to check internal API usage: {}

What it means

MojoExecutionException wrapping an IOException, thrown by KafkaInternalApiCheckerMojo.runCheck when PublicApiChecker.checkBytecode fails to read the class roots or kafka jars. The Maven analogue of Gradle error 1 — an I/O problem during the bytecode scan, with the original IOException preserved as cause.

Source

Thrown at api-checker/maven-plugin/src/main/java/org/apache/kafka/maven/KafkaInternalApiCheckerMojo.java:145

    private void handleNoKafkaDependency() throws MojoFailureException {
        String msg = "No org.apache.kafka:* dependencies found on the project classpath. "
                + "The checker cannot derive an API surface and would produce a meaningless "
                + "'0 violations' report — likely a classpath or configuration issue.";
        if (failOnNoKafkaDependency) {
            throw new MojoFailureException(msg);
        }
        getLog().warn(msg + " Skipping internal API check. "
                + "Set <failOnNoKafkaDependency>true</failOnNoKafkaDependency> to make this fatal.");
    }

    private void runCheck(List<File> kafkaJars, List<File> classRoots)
            throws MojoExecutionException, MojoFailureException {
        try {
            getLog().info("Scanning " + classRoots.size() + " class file root(s) for internal API usage");
            CheckResult result = new PublicApiChecker(kafkaJars).checkBytecode(classRoots);
            reportResults(result);
        } catch (IOException e) {
            throw new MojoExecutionException("Failed to check internal API usage: " + e.getMessage(), e);
        }
    }

    private void reportResults(CheckResult result) throws MojoFailureException, IOException {
        List<PublicApiViolation> violations = result.violations();
        List<PublicApiViolation> suppressions = result.suppressions();

        ViolationReporter reporter = new ViolationReporter();
        reporter.writeTextReport(violations, suppressions, reportFile);
        reporter.printToConsole(violations, suppressions);

        getLog().info("Internal API usage check completed. Report written to: " + reportFile.getAbsolutePath());

        long unjustified = suppressions.stream().filter(PublicApiViolation::lacksReason).count();
        if (unjustified > 0) {
            getLog().warn(unjustified + " suppression(s) carry no reason — KIP-1265 requires a justification on every @SuppressKafkaInternalApiUsage");
        }

View on GitHub (pinned to 996fb4585a)

Solutions

  1. Read the wrapped IOException cause to find the failing path.
  2. Run mvn clean compile to regenerate target/classes consistently.
  3. If a kafka jar is corrupt, delete it from ~/.m2/repository/org/apache/kafka/ and re-resolve.
  4. Validate that <classesDirectories> values exist on disk before the goal runs.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight in the mojo or a profile
for (File f : classRoots) if (!f.canRead()) throw new IllegalStateException("unreadable: " + f);

Try / catch

try { runCheck(...); } catch (MojoExecutionException e) { if (e.cause instanceof java.io.IOException) { getLog().error(e.cause.message); /* mvn clean, purge corrupt jar */ } else throw e; }

Prevention

When it happens

Trigger: new PublicApiChecker(kafkaJars).checkBytecode(classRoots) throws IOException inside the try at line 140. Triggers on unreadable/missing/deleted class roots or corrupt kafka jars.

Common situations: target/classes deleted between resolution and execution; corrupt kafka-clients jar in the local Maven repo (.m2); another process locking class files; classesDirectories pointing at a non-existent path.

Related errors


AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11). Data as JSON: /api/errors/a62b8b7a350e9f09. Report an issue: GitHub.