elastic/elasticsearch · error · IllegalArgumentException
Path [{}] is already exclusive to [{}]{}, cannot add exclusi
Error message
Path [{}] is already exclusive to [{}]{}, cannot add exclusive access for [{}][{}] What it means
Thrown by FileAccessTree.buildExclusivePathList when two different components both claim exclusive access to the same normalized path. An exclusive files-entitlement reserves a path for one component (and its modules); a second component trying to register the same path as exclusive is rejected. The message names both components, the existing module set, and the conflicting module.
Source
Thrown at libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/FileAccessTree.java:139
static List<ExclusivePath> buildExclusivePathList(
List<ExclusiveFileEntitlement> exclusiveFileEntitlements,
PathLookup pathLookup,
FileAccessTreeComparison comparison
) {
Map<String, ExclusivePath> exclusivePaths = new HashMap<>();
for (ExclusiveFileEntitlement efe : exclusiveFileEntitlements) {
for (FilesEntitlement.FileData fd : efe.filesEntitlement().filesData()) {
if (fd.exclusive()) {
List<Path> paths = fd.resolvePaths(pathLookup).toList();
for (Path path : paths) {
String normalizedPath = normalizePath(path);
var exclusivePath = exclusivePaths.computeIfAbsent(
normalizedPath,
k -> new ExclusivePath(efe.componentName(), new HashSet<>(), normalizedPath)
);
if (exclusivePath.componentName().equals(efe.componentName()) == false) {
throw new IllegalArgumentException(
"Path ["
+ normalizedPath
+ "] is already exclusive to ["
+ exclusivePath.componentName()
+ "]"
+ exclusivePath.moduleNames
+ ", cannot add exclusive access for ["
+ efe.componentName()
+ "]["
+ efe.moduleName
+ "]"
);
}
exclusivePath.moduleNames.add(efe.moduleName());
}
}
}
}View on GitHub (pinned to db6a809a66)
Solutions
- Audit the policy files for the two named components and remove or relocate the duplicate exclusive path claim.
- Assign the path to exactly one component; have the other use non-exclusive access if it genuinely needs shared read.
- Resolve symlinks/relative paths so each component points at a distinct directory.
- If both components legitimately share the dir, mark only one as exclusive.
Example fix
// before: two policies both claim /var/lib/es/data exclusively
server: { files: [{ path: /var/lib/es/data, exclusive: true }] }
pluginA: { files: [{ path: /var/lib/es/data, exclusive: true }] }
// after: only one exclusive claim
pluginA: { files: [{ path: /var/lib/es/pluginA-data, exclusive: true }] } Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate that no two components claim the same exclusive path
Map<String, String> owner = new HashMap<>();
for (var c : components) {
for (Path p : c.exclusivePaths()) {
String n = normalize(p);
if (owner.containsKey(n) && !owner.get(n).equals(c.name())) {
throw new IllegalArgumentException(n + " already exclusive to " + owner.get(n));
}
owner.putIfAbsent(n, c.name());
}
} Prevention
- Centralize exclusive-path allocation so two teams cannot claim the same dir.
- Resolve symlinks before declaring a path exclusive.
When it happens
Trigger: Two ExclusiveFileEntitlement entries from different componentName values resolve to the same normalized path with exclusive=true. computeIfAbsent records the first component; when the second component's path matches and the componentNames differ, the IllegalArgumentException fires.
Common situations: Two plugins each declare exclusive access to the same directory in their policy YAML; a server policy and a plugin policy both claim a data dir exclusively; path normalization (relative vs absolute, symlinks) makes two different-looking paths collide.
Related errors
- duplicate/overlapping exclusive paths found in files entitle
- 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/681747d5e937d12c.
Report an issue: GitHub.