elastic/elasticsearch · error · GradleException

Found invalid file permissions: {}

Error message

Found invalid file permissions:
{}

What it means

The intended result of FilePermissionsTask: one or more source files have an executable bit set (OWNER/GROUP/OTHERS_EXECUTE). Java source files must not be executable; the task fails the build listing each offending file. It is a hygiene check, not an infrastructure fault.

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/FilePermissionsTask.java:106

            .stream()
            .map(sourceTree -> sourceTree.matching(filesFilter))
            .reduce(FileTree::plus)
            .orElse(projectLayout.files().getAsFileTree());
    }

    @TaskAction
    public void checkInvalidPermissions() throws IOException {
        if (OS.current() == OS.WINDOWS) {
            throw new StopExecutionException();
        }
        List<String> failures = getFiles().getFiles()
            .stream()
            .filter(FilePermissionsTask::isExecutableFile)
            .map(file -> "Source file is executable: " + file)
            .collect(Collectors.toList());

        if (failures.isEmpty() == false) {
            throw new GradleException("Found invalid file permissions:\n" + String.join("\n", failures));
        }

        outputMarker.getParentFile().mkdirs();
        Files.writeString(outputMarker.toPath(), "done");
    }

    @OutputFile
    public File getOutputMarker() {
        return outputMarker;
    }

    @Internal
    public abstract ListProperty<FileTree> getSources();
}

View on GitHub (pinned to db6a809a66)

Solutions

  1. Remove the executable bit from every listed file: chmod -x <each listed file>.
  2. Bulk-fix the repo: git ls-files -z '*.java' | xargs -0 chmod -x, then commit.
  3. Find what set the bit (a hook, an editor, a packaging step) to prevent recurrence.
  4. Re-run the filePermissions task to confirm clean.

Example fix

# before: src/main/java/Foo.java has mode 0755
# after
chmod -x src/main/java/Foo.java   # now 0644
Defensive patterns

Strategy: validation

Validate before calling

// Pre-build hook: fail fast listing any executable source files before the task runs
try (Stream<Path> s = Files.walk(Path.of("src"))) {
    List<Path> exec = s.filter(Files::isRegularFile)
        .filter(p -> Files.isExecutable(p))
        .toList();
    if (!exec.isEmpty()) throw new IllegalStateException("Executable source files: " + exec);
}

Prevention

When it happens

Trigger: Any file under getSources() has at least one execute permission bit set, detected via POSIX readAttributes. Skipped entirely on Windows (StopExecutionException).

Common situations: A script accidentally chmod +x'd a .java file; files copied from a Windows zip with all-bits-set; a CI image that sets executable bits; running chmod -R +x on the repo by mistake.

Related errors


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