elastic/elasticsearch · error · GradleException

Cannot generate license header report for ${path}

Error message

Cannot generate license header report for ${path}

What it means

generateReport deletes the previous report file, opens an XML writer, and delegates to RAT's toXmlReportFile which scans every source file. Any IOException or RatException from that pipeline — writer failure, RAT analysis error, inability to create the report file — is wrapped as this GradleException prefixed with the task's path.

Source

Thrown at build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/precommit/LicenseHeadersTask.java:303

    }

    private IHeaderMatcher subStringMatcher(String licenseFamilyCategory, String licenseFamilyName, String substringPattern) {
        SubstringLicenseMatcher substringLicenseMatcher = new SubstringLicenseMatcher();
        substringLicenseMatcher.setLicenseFamilyCategory(licenseFamilyCategory);
        substringLicenseMatcher.setLicenseFamilyName(licenseFamilyName);
        SubstringLicenseMatcher.Pattern pattern = new SubstringLicenseMatcher.Pattern();
        pattern.setSubstring(substringPattern);
        substringLicenseMatcher.addConfiguredPattern(pattern);
        return substringLicenseMatcher;
    }

    private ClaimStatistic generateReport(ReportConfiguration config, File xmlReportFile) {
        try {
            Files.deleteIfExists(reportFile.get().getAsFile().toPath());
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(xmlReportFile));
            return toXmlReportFile(config, bufferedWriter);
        } catch (IOException | RatException exception) {
            throw new GradleException("Cannot generate license header report for " + getPath(), exception);
        }
    }

    private ClaimStatistic toXmlReportFile(ReportConfiguration config, Writer writer) throws RatException, IOException {
        ClaimStatistic stats = new ClaimStatistic();
        RatReport standardReport = XmlReportFactory.createStandardReport(new XmlWriter(writer), stats, config);

        standardReport.startReport();
        for (FileCollection dirSet : getSourceFolders().get()) {
            for (File f : dirSet.getAsFileTree().matching(patternFilterable -> patternFilterable.exclude(getExcludes()))) {
                standardReport.report(new FileDocument(f));
            }
        }
        standardReport.endReport();
        writer.flush();
        writer.close();
        return stats;
    }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Ensure build/reports/licenseHeaders/ is writable and its parent exists.
  2. Inspect the caused-by exception — RatException vs IOException points to different causes.
  3. Verify the RAT dependency version matches what build-conventions expects.
  4. Clean the build directory: `./gradlew clean` and rerun.

Example fix

// before: report dir on read-only volume
// after: point gradle build dir at a writable location
./gradlew licenseHeaders -Dorg.gradle.buildDir=/tmp/es-build
Defensive patterns

Strategy: try-catch

Validate before calling

File reportDir = reportFile.getAsFile().get().getParentFile();
if (!reportDir.exists() && !reportDir.mkdirs()) {
    throw new GradleException("Cannot create license report dir: " + reportDir);
}

Try / catch

try {
    ClaimStatistic stats = generateReport(config, reportXml);
} catch (GradleException e) {
    if (e.getMessage().startsWith("Cannot generate license header report")) {
        // inspect e.getCause(): IOException -> fs/disk; RatException -> input
        throw new GradleException("License report generation failed: " + e.getCause(), e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: The report output directory does not exist or is not writable; a RAT document analysis throws RatException on a malformed input; a disk/encoding IOException while writing the XML; the reportFile path is on a read-only filesystem.

Common situations: Building on a read-only filesystem or container volume; an older RAT version incompatible with the inputs; a path collision where reportFile is also a source input; permissions on the build/ directory.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/4774bf3c4df164f5. Report an issue: GitHub.