{"record":{"id":"e54f4969b35141d8","repo":"apache/kafka","slug":"found-d-internal-api-usage-violations-see-report","errorCode":null,"errorMessage":"Found %d internal API usage violations. See report: %s","messagePattern":"Found (.+?) internal API usage violations\\. See report: (.+?)","errorType":"validation","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"api-checker/gradle-plugins/src/main/java/org/apache/kafka/gradle/KafkaInternalApiCheckerTask.java","lineNumber":148,"sourceCode":"        reporter.writeTextReport(violations, suppressions, report);\n        reporter.printToConsole(violations, suppressions);\n\n        getLogger().info(\"Internal API usage check completed. Report written to: {}\", report.getAbsolutePath());\n\n        long unjustified = suppressions.stream().filter(PublicApiViolation::lacksReason).count();\n        if (unjustified > 0) {\n            getLogger().warn(\"{} suppression(s) carry no reason — KIP-1265 requires a justification on every @SuppressKafkaInternalApiUsage\", unjustified);\n        }\n\n        if (violations.isEmpty()) {\n            getLogger().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(), report.getAbsolutePath());\n        if (failOnViolation.get()) {\n            throw new GradleException(message);\n        }\n        getLogger().warn(message);\n    }\n\n    @Input\n    public Property<Boolean> getCheckerEnabled() {\n        return enabled;\n    }\n\n    @Input\n    public Property<Boolean> getFailOnViolation() {\n        return failOnViolation;\n    }\n\n    @Input\n    public Property<Boolean> getFailOnNoKafkaDependency() {\n        return failOnNoKafkaDependency;\n    }","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/apache/kafka/blob/996fb4585aa1bcc8980b0e1b8d6b168b986cd979/api-checker/gradle-plugins/src/main/java/org/apache/kafka/gradle/KafkaInternalApiCheckerTask.java#L130-L166","documentation":"GradleException thrown by KafkaInternalApiCheckerTask.reportResults when the bytecode scan found one or more references to internal Kafka APIs and failOnViolation is true (the default). The message includes the violation count and the path to the text report. This is the task's primary failure mode — it is signalling real illegal usage of internal API.","triggerScenarios":"violations list is non-empty after PublicApiChecker.checkBytecode (line 116) and failOnViolation.get() is true (line 148). Triggered when compiled .class files in the configured classDirs reference package-private or @InternalApi-marked Kafka symbols.","commonSituations":"Consuming org.apache.kafka.* internal package types, accessing classes marked with the internal API annotation, depending on a Kafka type that was public in one version but moved to internal in another, or forgetting to annotate legitimate usage with @SuppressKafkaInternalApiUsage.","solutions":["Open the report at the path named in the message and read each PublicApiViolation to see which internal symbol is referenced.","Replace the internal API usage with the documented public equivalent (e.g. use Admin/Producer/Consumer APIs instead of package-private helpers).","If the usage is intentional and justified, annotate it with @SuppressKafkaInternalApiUsage(reason = \"...\") — KIP-1265 requires a non-empty reason.","Temporarily set kafkaInternalApiChecker.failOnViolation = false to make it a warning while you triage (do not ship this way)."],"exampleFix":"// before — references internal helper\nimport org.apache.kafka.common.internals.PluginUtils;\nPluginUtils.pluginClassLoader(...);\n// after — annotate with justification per KIP-1265\n@SuppressKafkaInternalApiUsage(reason = \"Classloader isolation in connector X, no public equivalent\")\nPluginUtils.pluginClassLoader(...);","handlingStrategy":"validation","validationCode":"// Use the checker's dry-run: set failOnViolation=false in a 'triage' run, parse the report, then fix or suppress.\nkafkaInternalApiChecker.failOnViolation = false","typeGuard":null,"tryCatchPattern":"try { tasks.checkInternalApiUsage() } catch (GradleException e) { if (e.message.contains('internal API usage violations')) { /* read report, suppress with reason, or migrate API */ } else throw e }","preventionTips":["Keep failOnViolation=true in CI so violations surface early.","Always include a non-empty reason on @SuppressKafkaInternalApiUsage.","Prefer public Admin/Producer/Consumer APIs over package-private helpers."],"tags":["gradle","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"}