{"record":{"id":"19a467ef91a3c8da","repo":"apache/kafka","slug":"found-d-internal-api-usage-violations-see-report-19a467","errorCode":null,"errorMessage":"Found %d internal API usage violations. See report: %s","messagePattern":"Found (.+?) internal API usage violations\\. See report: (.+?)","errorType":"validation","errorClass":"MojoFailureException","httpStatus":null,"severity":"error","filePath":"api-checker/maven-plugin/src/main/java/org/apache/kafka/maven/KafkaInternalApiCheckerMojo.java","lineNumber":172,"sourceCode":"        reporter.writeTextReport(violations, suppressions, reportFile);\n        reporter.printToConsole(violations, suppressions);\n\n        getLog().info(\"Internal API usage check completed. Report written to: \" + reportFile.getAbsolutePath());\n\n        long unjustified = suppressions.stream().filter(PublicApiViolation::lacksReason).count();\n        if (unjustified > 0) {\n            getLog().warn(unjustified + \" suppression(s) carry no reason — KIP-1265 requires a justification on every @SuppressKafkaInternalApiUsage\");\n        }\n\n        if (violations.isEmpty()) {\n            getLog().info(\"No internal API usage found.\");\n            return;\n        }\n\n        String message = String.format(\"Found %d internal API usage violations. See report: %s\",\n                violations.size(), reportFile.getAbsolutePath());\n        if (failOnViolation) {\n            throw new MojoFailureException(message);\n        }\n        getLog().warn(message);\n    }\n\n    /**\n     * Default to the project's main compiled output, matching the Gradle plugin's behaviour\n     * (which feeds {@code sourceSets.main.output.classesDirs}). Test code legitimately uses\n     * internal/test utilities, so including it by default would create noise that isn't a\n     * real consumer-side concern. Users who want to scan test code can opt in by setting\n     * {@code <classesDirectories>} explicitly.\n     */\n    private List<File> getDefaultClassesDirectories() {\n        List<File> dirs = new ArrayList<>();\n        File mainClasses = new File(project.getBuild().getOutputDirectory());\n        if (mainClasses.exists()) {\n            dirs.add(mainClasses);\n        }\n        return dirs;","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/apache/kafka/blob/996fb4585aa1bcc8980b0e1b8d6b168b986cd979/api-checker/maven-plugin/src/main/java/org/apache/kafka/maven/KafkaInternalApiCheckerMojo.java#L154-L190","documentation":"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.","triggerScenarios":"violations non-empty after checkBytecode and failOnViolation true (line 173). The compiled classes reference package-private or @InternalApi Kafka symbols.","commonSituations":"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.","solutions":["Read the report at reportFile.getAbsolutePath() — each violation names the offending internal symbol.","Migrate the usage to the public Kafka API (Admin/Producer/Consumer/common utilities).","Annotate justified usage with @SuppressKafkaInternalApiUsage(reason=\"...\") per KIP-1265.","While triaging, set <failOnViolation>false</failOnViolation> to convert to a warning; do not leave it that way in production."],"exampleFix":"// before\nimport org.apache.kafka.common.utils.Implicits;\n// after\n@SuppressKafkaInternalApiUsage(reason=\"No public equivalent for X; tracked in KAFKA-NNNNN\")\nimport org.apache.kafka.common.utils.Implicits;","handlingStrategy":"validation","validationCode":"<!-- triage run -->\n<configuration><failOnViolation>false</failOnViolation></configuration>","typeGuard":null,"tryCatchPattern":"try { kafkaInternalApiChecker.execute(); } catch (MojoFailureException e) { if (e.message.contains('internal API usage violations')) { /* read reportFile, suppress with reason, or migrate */ } else throw e; }","preventionTips":["Keep failOnViolation=true in CI.","Always supply a reason when suppressing.","Prefer public Kafka APIs."],"tags":["maven","api-checker","violation","internal-api"],"backgroundTag":null,"analyzedSha":"996fb4585aa1bcc8980b0e1b8d6b168b986cd979","analyzedAt":"2026-08-11T22:03:28.655Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}