apache/dolphinscheduler · error · IllegalArgumentException
failed to download to ${fileDownloadPathNormalized}
Error message
failed to download to ${fileDownloadPathNormalized} What it means
CosStorageOperator.download resolves the destination path under FileUtils.DATA_BASEDIR (the DS temp folder) and refuses to write anywhere else. If the normalized destination escapes that folder, it throws IllegalArgumentException to block path traversal outside the sandbox.
Source
Thrown at dolphinscheduler-storage-plugin/dolphinscheduler-storage-cos/src/main/java/org/apache/dolphinscheduler/plugin/storage/cos/CosStorageOperator.java:145
throw new FileAlreadyExistsException("directory: " + cosKey + " already exists");
}
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(0L);
InputStream emptyContent = new ByteArrayInputStream(new byte[0]);
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, cosKey, emptyContent, metadata);
cosClient.putObject(putObjectRequest);
}
@SneakyThrows
@Override
public void download(String srcFilePath, String dstFilePath, boolean overwrite) {
String cosKey = transformAbsolutePathToCOSKey(srcFilePath);
Path dsTempFolder = Paths.get(FileUtils.DATA_BASEDIR).normalize().toAbsolutePath();
Path fileDownloadPathNormalized = dsTempFolder.resolve(dstFilePath).normalize().toAbsolutePath();
if (!fileDownloadPathNormalized.startsWith(dsTempFolder)) {
// if the destination file path is NOT in DS temp folder (e.g., '/tmp/dolphinscheduler'),
// an IllegalArgumentException should be thrown.
throw new IllegalArgumentException("failed to download to " + fileDownloadPathNormalized);
}
File dstFile = fileDownloadPathNormalized.toFile();
if (dstFile.isDirectory()) {
Files.delete(dstFile.toPath());
} else {
FileUtils.createDirectoryWithPermission(dstFile.getParentFile().toPath(), FileUtils.PERMISSION_755);
}
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, cosKey);
Download download = cosTransferManager.download(getObjectRequest, dstFile);
download.waitForCompletion();
}
@Override
public boolean exists(String fileName) {
String cosKey = transformAbsolutePathToCOSKey(fileName);
return cosClient.doesObjectExist(bucketName, cosKey);
}View on GitHub (pinned to 02eac45a1b)
Solutions
- Pass a path RELATIVE to the DS temp folder as dstFilePath
- Strip/normalize '..' segments and any leading '/' from user-supplied destination paths before calling download
- If the file truly must go elsewhere, download into the temp folder then move it with your own code
Example fix
// before operator.download(srcPath, "/data/out/result.csv"); // after operator.download(srcPath, "resources/out/result.csv"); // stays inside DATA_BASEDIR
Defensive patterns
Strategy: validation
Validate before calling
Path base = Paths.get(FileUtils.DATA_BASEDIR).normalize().toAbsolutePath();
Path dst = base.resolve(userDst).normalize().toAbsolutePath();
if (!dst.startsWith(base)) throw new IllegalArgumentException("dst must be inside DS temp folder"); Try / catch
try {
operator.download(src, dst);
} catch (IllegalArgumentException e) {
log.error("Destination escaped DS temp folder: {}", dst);
} Prevention
- Always pass destinations relative to the DS temp folder
- Sanitize '..' and leading '/' from user-supplied paths
- Never concatenate raw user input into the destination path
When it happens
Trigger: Calling download(srcFilePath, dstFilePath) where dstFilePath resolves (after normalize().toAbsolutePath()) outside the dolphinscheduler temp base dir — e.g., an absolute dstFilePath like '/etc/foo' or a path containing enough '../' segments to escape.
Common situations: Passing an absolute destination path instead of a relative one; user-supplied resource paths containing '..'; misconfigured task output paths pointing to other system directories.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- directory: ${cosKey} already exists
- file: ${dstPath} already exists
- Update the resource file from content: {fileAbsolutePath} fa
- Download the resource file: {fileAbsolutePath} failed
- ILLEGAL_RESOURCE_PATH
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/1221730a2e9e5fea.
Report an issue: GitHub.