{"record":{"id":"cb2d5392163fcd54","repo":"elastic/elasticsearch","slug":"forbidden-api-verification-failed","errorCode":null,"errorMessage":"Forbidden API verification failed","messagePattern":"Forbidden API verification failed","errorType":"exception","errorClass":"VerificationException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/CheckForbiddenApisTask.java","lineNumber":541,"sourceCode":"                    if (checker.noSignaturesFilesParsed()) {\n                        throw new InvalidUserDataException(\n                            \"No signatures were added to task; use properties 'signatures', 'bundledSignatures', 'signaturesURLs', and/or 'signaturesFiles' to define those!\"\n                        );\n                    } else {\n                        logger.info(\"Skipping execution because no API signatures are available.\");\n                        return;\n                    }\n                }\n\n                try {\n                    checker.addClassesToCheck(getParameters().getClassFiles());\n                } catch (IOException ioe) {\n                    throw new GradleException(\"Failed to load one of the given class files.\", ioe);\n                }\n                checker.run();\n                writeMarker(getParameters().getSuccessMarker().getAsFile().get());\n            } catch (ForbiddenApiException e) {\n                throw new VerificationException(\"Forbidden API verification failed\", e);\n            } catch (Exception e) {\n                throw new RuntimeException(e);\n            } finally {\n                // Close the classloader to free resources:\n                try {\n                    if (urlLoader != null) urlLoader.close();\n                } catch (IOException ioe) {\n                    // getLogger().warn(\"Cannot close classloader: \".concat(ioe.toString()));\n                }\n            }\n        }\n\n        private void writeMarker(File successMarker) throws IOException {\n            Files.write(successMarker.toPath(), new byte[] {}, StandardOpenOption.CREATE);\n        }\n\n        private URLClassLoader createClassLoader(FileCollection classpath, FileCollection classesDirs) {\n            if (classesDirs == null || classpath == null) {","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/CheckForbiddenApisTask.java#L523-L559","documentation":"The actual forbidden-API violation result: checker.run() raised a ForbiddenApiException, which the task wraps in a Gradle VerificationException. This is the task doing its job — it found a reference to an API that the configured signatures forbid (e.g. System.out, internal JDK APIs, deprecated APIs). It is a code-quality failure, not an infrastructure fault.","triggerScenarios":"Any class in getClassFiles() references a method/field/package listed in the configured signatures or bundled signatures; the checker reports each violation then throws.","commonSituations":"New code that uses System.out/err, an internal sun.* API, a deprecated method, or an unsafe deserialization API; pulling in a dependency that itself was compiled against now-forbidden APIs; tightening bundledSignatures.","solutions":["Read the VerificationException's cause and the preceding checker output lines — they name each violating class, method, and which signature matched.","Fix the offending code to use the permitted alternative (SLF4J/LogManager logger instead of System.out, public API instead of sun.*, etc.).","If the call is genuinely required, scope a suppress annotation or a narrowly-targeted signatures relaxation per the project's policy.","Do NOT widen the suppression broadly; re-run the task to confirm zero violations."],"exampleFix":"// before\nSystem.out.println(\"debug: \" + value);\n\n// after\nprivate static final Logger logger = LogManager.getLogger(Foo.class);\nlogger.debug(\"debug: {}\", value);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    checker.run();\n} catch (ForbiddenApiException e) {\n    // expected path when violations exist: the task wraps it in VerificationException.\n    // Each violation is already logged above; fix the cited call sites, do not catch-and-ignore in real builds.\n    throw e;\n}","preventionTips":["Never catch-and-ignore VerificationException — fix the violation.","Run forbidden-apis in CI on every PR to catch new violations early.","Use the project logger instead of System.out to avoid the most common bundled signature.","Prefer public APIs over sun.*/internal.* and avoid @Deprecated methods."],"tags":["gradle","forbidden-apis","precommit","code-quality","verification"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}