elastic/elasticsearch · error · IllegalArgumentException
extra config file destination can't be relative, was {} for
Error message
extra config file destination can't be relative, was {} for {} What it means
Thrown by the single-arg extraConfigFile(destination, from) overload when the destination string contains '..'. The check blocks path traversal: destinations are resolved against the config dir, so '..' would escape it and potentially overwrite arbitrary files in the distro. IllegalArgumentException because it is a misuse of the API, not a runtime cluster fault.
Source
Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java:718
if (Files.exists(destination) == false) {
fileSystemOperations.copy(spec -> {
if (module.get().getName().toLowerCase().endsWith(".zip")) {
spec.from(archiveOperations.zipTree(module));
} else if (module.get().isDirectory()) {
spec.from(module);
} else {
throw new IllegalArgumentException("Not a valid module " + module + " for " + this);
}
spec.into(destination);
});
}
}
}
@Override
public void extraConfigFile(String destination, File from) {
if (destination.contains("..")) {
throw new IllegalArgumentException("extra config file destination can't be relative, was " + destination + " for " + this);
}
extraConfigFiles.put(destination, from);
}
@Override
public void extraConfigFile(String destination, File from, PropertyNormalization normalization) {
if (destination.contains("..")) {
throw new IllegalArgumentException("extra config file destination can't be relative, was " + destination + " for " + this);
}
extraConfigFiles.put(destination, from, normalization);
}
@Override
public void extraJarFiles(FileCollection from) {
extraJarConfigurations.add(from);
}
@OverrideView on GitHub (pinned to db6a809a66)
Solutions
- Use a destination path that stays under the config directory (no '..').
- If you need a file outside config/, use a different hook (e.g. extraJarFiles for lib, or write a custom task).
- If '..' appears inside a legitimate filename, rename the file to avoid the substring.
- On Windows, use forward slashes or a plain filename; avoid mixing separators that introduce '..'.
Example fix
// before: tries to escape config dir
extraConfigFile('../elasticsearch.yml', myFile)
// after: keep destination under config/
extraConfigFile('elasticsearch.yml', myFile) Defensive patterns
Strategy: validation
Validate before calling
static String safeExtraConfigDest(String dest) {
if (dest.contains("..")) {
throw new IllegalArgumentException("extra config dest must not contain '..': " + dest);
}
return dest;
}
// Use: node.extraConfigFile(safeExtraConfigDest("log4j2.xml"), file); Type guard
// True when destination stays within the config tree (no traversal)
static boolean isSafeConfigDest(String dest) {
return !dest.contains("..") && !dest.startsWith("/");
} Prevention
- Keep destinations relative to the config dir and free of '..'.
- Avoid filenames containing '..' (the substring check is naive).
- Prefer forward-slash relative paths.
When it happens
Trigger: Calling extraConfigFile('../elasticsearch.yml', file), extraConfigFile('certs/../../scripts/x', file), or any destination string containing the literal substring '..' (the check is naive: it flags '..' anywhere, including inside filenames like 'my..file').
Common situations: Deliberate attempt to write outside config/. Accidental absolute path or Windows backslash causing the '..' substring. Filename containing '..' (false positive due to the substring check).
Related errors
- Unknown keys in user definition {} for {}
- supplied keystore file {} does not exist, require for {}
- Can't create extra config file from {} for {} as it does not
- extra jar file {} doesn't appear to be a JAR
- Can't create roles.yml config file from {} for {} as it does
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/5a457541a377bb20.
Report an issue: GitHub.