apache/kafka · error · MojoFailureException

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

Error message

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

What it means

Thrown by the kafka-internal-api-checker Maven plugin (MojoFailureException) when bytecode scanning of the project's compiled classes finds references to Kafka internal (non-public) APIs and the <failOnViolation> flag is true. It enforces KIP-1265 / the @SuppressKafkaInternalApiUsage discipline so consumers of kafka-clients do not silently bind to unstable internals. The message reports the violation count and points to the text report written to <reportFile>.

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 c31c9215e1)

Solutions

  1. Open the report at the path printed in the message and read each PublicApiViolation entry to see which internal symbol is referenced and from which class.
  2. Refactor the offending call site to use the supported public API equivalent (e.g. AdminClient / KafkaClient APIs listed in build.gradle javadoc includes).
  3. If the usage is intentional and justified, annotate with @SuppressKafkaInternalApiUsage(reason=...) per KIP-1265 so it is recorded as a suppression rather than a violation.
  4. Temporarily set <failOnViolation>false</failOnViolation> in the plugin configuration to unblock CI while the fix is prepared (not recommended as a permanent state).

Example fix

// before
org.apache.kafka.common.protocol.ApiKeys apikey = org.apache.kafka.common.protocol.ApiKeys.METADATA;
// after (use public API or suppress)
@SuppressKafkaInternalApiUsage(reason = "Need APIKeys ordinal for wire compat shim, tracked in KAFKA-12345")
org.apache.kafka.common.protocol.ApiKeys apikey = org.apache.kafka.common.protocol.ApiKeys.METADATA;
Defensive patterns

Strategy: validation

Validate before calling

// This is a Maven-plugin build failure (MojoFailureException), not a runtime
// exception. Gate the build *before* enabling failOnViolation:
//   1. Configure <failOnViolation>false</failOnViolation> in pom.xml.
//   2. Read the report at ${project.build.directory}/reports/kafka-internal-api-usage.txt.
//   3. For each VIOLATION line, replace the internal-API call with a public API
//      equivalent, or annotate the call site:
//          @SuppressKafkaInternalApiUsage(reason="<why public API cannot be used>")
//   4. Re-enable <failOnViolation>true</failOnViolation> only when violations == 0.
//
// CI gate (Groovy/shell) before promoting the build:
//   report="${project.build.directory}/reports/kafka-internal-api-usage.txt"
//   n=$(grep -c '^VIOLATION' "$report" || true)
//   [ "$n" -eq 0 ] || { echo "Fix $n internal-API violations first"; exit 1; }

Prevention

When it happens

Trigger: Binding the kafka-internal-api-checker:maven-plugin goal to the build and having compiled classes that reference org.apache.kafka.* packages outside the public API include list. Triggered during the verify/package phase once classes are compiled. Only fails when failOnViolation=true (the message degrades to a warn otherwise).

Common situations: Upgrading the kafka-clients dependency to a version whose internal classes were refactored/removed, after a transitive dependency starts reaching into internals, or when a previously-public class was reclassified as internal. CI builds that newly enable the plugin will surface long-standing violations for the first time.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/19a467ef91a3c8da.json. Report an issue: GitHub.