apache/kafka · error · MojoFailureException

Found internal API usage violations. See report

Error message

Found %d internal API usage violations. See report: %s

What it means

MojoFailureException thrown by KafkaInternalApiCheckerMojo.reportResults when the bytecode scan found internal Kafka API usage violations and failOnViolation is true. Message includes the violation count and the report path. The Maven analogue of Gradle error 2 — the primary signal that the project uses internal Kafka APIs.

Solutions

  1. Read the report at reportFile.getAbsolutePath() — each violation names the offending internal symbol.
  2. Migrate the usage to the public Kafka API (Admin/Producer/Consumer/common utilities).
  3. Annotate justified usage with @SuppressKafkaInternalApiUsage(reason="...") per KIP-1265.
  4. While triaging, set <failOnViolation>false</failOnViolation> to convert to a warning; do not leave it that way in production.

Example fix

// before
import org.apache.kafka.common.utils.Implicits;
// after
@SuppressKafkaInternalApiUsage(reason="No public equivalent for X; tracked in KAFKA-NNNNN")
import org.apache.kafka.common.utils.Implicits;
Defensive patterns

Strategy: validation

Validate before calling

<!-- triage run -->
<configuration><failOnViolation>false</failOnViolation></configuration>

Try / catch

try { kafkaInternalApiChecker.execute(); } catch (MojoFailureException e) { if (e.message.contains('internal API usage violations')) { /* read reportFile, suppress with reason, or migrate */ } else throw e; }

Prevention

When it happens

Trigger: violations non-empty after checkBytecode and failOnViolation true (line 173). The compiled classes reference package-private or @InternalApi Kafka symbols.

Common situations: Using org.apache.kafka.* internal package types; depending on a type that became internal in a newer kafka version; legitimate usage not annotated with @SuppressKafkaInternalApiUsage.

Related errors


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

Appendix: source

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

        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");
        }

        if (violations.isEmpty()) {
            getLog().info("No internal API usage found.");
            return;
        }

        String message = String.format("Found %d internal API usage violations. See report: %s",
                violations.size(), reportFile.getAbsolutePath());
        if (failOnViolation) {
            throw new MojoFailureException(message);
        }
        getLog().warn(message);
    }

    /**
     * Default to the project's main compiled output, matching the Gradle plugin's behaviour
     * (which feeds {@code sourceSets.main.output.classesDirs}). Test code legitimately uses
     * internal/test utilities, so including it by default would create noise that isn't a
     * real consumer-side concern. Users who want to scan test code can opt in by setting
     * {@code <classesDirectories>} explicitly.
     */
    private List<File> getDefaultClassesDirectories() {
        List<File> dirs = new ArrayList<>();
        File mainClasses = new File(project.getBuild().getOutputDirectory());
        if (mainClasses.exists()) {
            dirs.add(mainClasses);
        }
        return dirs;

View on GitHub (pinned to 996fb4585a)