elastic/elasticsearch · error · IllegalArgumentException
duplicate/overlapping exclusive paths found in files entitle
Error message
duplicate/overlapping exclusive paths found in files entitlements: {} and {} What it means
Thrown by FileAccessTree.validateExclusivePaths when two exclusive paths are identical or one is a parent (ancestor) of another within the same sorted list. Even if the components are the same, nested or duplicated exclusive paths create ambiguity and are rejected. The check uses the comparison's path comparator and isParent/samePath predicates, so it is platform-aware (separator, case).
Source
Thrown at libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/FileAccessTree.java:168
+ "]"
);
}
exclusivePath.moduleNames.add(efe.moduleName());
}
}
}
}
return exclusivePaths.values().stream().sorted(comparing(ExclusivePath::path, comparison.pathComparator())).distinct().toList();
}
static void validateExclusivePaths(List<ExclusivePath> exclusivePaths, FileAccessTreeComparison comparison) {
if (exclusivePaths.isEmpty() == false) {
ExclusivePath currentExclusivePath = exclusivePaths.get(0);
for (int i = 1; i < exclusivePaths.size(); ++i) {
ExclusivePath nextPath = exclusivePaths.get(i);
if (comparison.samePath(currentExclusivePath.path(), nextPath.path)
|| comparison.isParent(currentExclusivePath.path(), nextPath.path())) {
throw new IllegalArgumentException(
"duplicate/overlapping exclusive paths found in files entitlements: " + currentExclusivePath + " and " + nextPath
);
}
currentExclusivePath = nextPath;
}
}
}
@SuppressForbidden(reason = "we need the separator as a char, not a string")
static char separatorChar() {
return File.separatorChar;
}
private static final Logger logger = LogManager.getLogger(FileAccessTree.class);
private static final String FILE_SEPARATOR = getDefaultFileSystem().getSeparator();
static final FileAccessTreeComparison DEFAULT_COMPARISON = Platform.LINUX.isCurrent()
? new CaseSensitiveComparison(separatorChar())
: new CaseInsensitiveComparison(separatorChar());View on GitHub (pinned to db6a809a66)
Solutions
- Merge the nested exclusive paths into the single broadest (parent) entry.
- Remove the duplicate sub-path entry from the policy.
- Run the paths through a normalizer and de-duplicate before declaring them exclusive.
Example fix
// before
files:
- { path: /var/lib/es/data, exclusive: true }
- { path: /var/lib/es/data/sub, exclusive: true }
// after: keep only the parent
files:
- { path: /var/lib/es/data, exclusive: true } Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate: no exclusive path is a parent of another
List<Path> sorted = paths.stream().sorted().toList();
for (int i = 1; i < sorted.size(); i++) {
if (sorted.get(i).startsWith(sorted.get(i - 1))) {
throw new IllegalArgumentException("overlapping exclusive paths: " + sorted.get(i-1) + " >= " + sorted.get(i));
}
} Prevention
- Declare only the broadest directory as exclusive; drop nested sub-paths.
- De-duplicate policy paths after normalization.
When it happens
Trigger: After sorting exclusive paths, the loop finds a pair where comparison.samePath(prev, next) or comparison.isParent(prev, next) is true. Happens when a policy lists both a directory and a subdirectory as exclusive, or lists the same path twice.
Common situations: A policy YAML lists '/data' and '/data/logs' both as exclusive; copy-paste duplication of a path entry; relative vs absolute forms of the same path both present; Windows backslash vs forward-slash normalization edge cases.
Related errors
- Path [{}] is already exclusive to [{}]{}, cannot add exclusi
- Error occurred when inspecting class: {}; SerializedLambda r
- Error occurred when inspecting class: {}
- Proxy fallback only supports instance method references; no
- Method reference passed to 'calling()' does not belong to {}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/f54c74fb8c080c91.
Report an issue: GitHub.