apache/dolphinscheduler · error · FileAlreadyExistsException
directory: ${directoryAbsolutePath} already exists
Error message
directory: ${directoryAbsolutePath} already exists What it means
GcsStorageOperator.createStorageDir creates a GCS 'directory' by writing an empty blob at the transformed key. If a blob already exists at that key it throws FileAlreadyExistsException rather than overwriting, since GCS directories are only prefix conventions.
Source
Thrown at dolphinscheduler-storage-plugin/dolphinscheduler-storage-gcs/src/main/java/org/apache/dolphinscheduler/plugin/storage/gcs/GcsStorageOperator.java:100
}
@Override
public String getStorageBaseDirectory() {
// All directory should end with File.separator
if (resourceBaseAbsolutePath.startsWith("/")) {
log.warn("{} -> {} should not start with / in Gcs", StorageConstants.RESOURCE_UPLOAD_PATH,
resourceBaseAbsolutePath);
return resourceBaseAbsolutePath.substring(1);
}
return getStorageBaseDirectory();
}
@SneakyThrows
@Override
public void createStorageDir(String directoryAbsolutePath) {
directoryAbsolutePath = transformAbsolutePathToGcsKey(directoryAbsolutePath);
if (exists(directoryAbsolutePath)) {
throw new FileAlreadyExistsException("directory: " + directoryAbsolutePath + " already exists");
}
BlobInfo blobInfo = BlobInfo.newBuilder(BlobId.of(bucketName, directoryAbsolutePath)).build();
gcsStorage.create(blobInfo, EMPTY_STRING.getBytes(StandardCharsets.UTF_8));
}
@SneakyThrows
@Override
public void download(String srcFilePath, String dstFilePath, boolean overwrite) {
srcFilePath = transformAbsolutePathToGcsKey(srcFilePath);
File dstFile = new File(dstFilePath);
if (dstFile.isDirectory()) {
Files.delete(dstFile.toPath());
} else {
FileUtils.createDirectoryWithPermission(dstFile.getParentFile().toPath(), FileUtils.PERMISSION_755);
}
Blob blob = gcsStorage.get(BlobId.of(bucketName, srcFilePath));View on GitHub (pinned to 02eac45a1b)
Solutions
- Check exists() first and skip creation if it returns true
- Delete the existing blob via gcsStorage/Blob.delete if overwrite is safe, then retry
- Use a unique directory path (tenant/timestamp scoped)
Example fix
// before
gcs.createStorageDir(dirPath);
// after
if (!gcs.exists(dirPath)) {
gcs.createStorageDir(dirPath);
} Defensive patterns
Strategy: validation
Validate before calling
if (gcs.exists(gcsKey)) { /* skip or pick another directory */ } Try / catch
try {
gcs.createStorageDir(dir);
} catch (FileAlreadyExistsException e) {
log.info("GCS directory already exists, reusing: {}", dir);
} Prevention
- Guard creation with exists()
- Use per-execution unique directory paths
- Recall that GCS 'directories' are empty blobs at key boundaries
When it happens
Trigger: Calling createStorageDir(directoryAbsolutePath) when exists(directoryAbsolutePath) finds an existing blob at the GCS key — from a previous mkdir, a file uploaded to the same path, or a leftover marker blob.
Common situations: Re-running workflows that recreate the same resource directory; an uploaded file occupying the directory key; stale blobs after resource reorganization.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- file: ${dstPath} already exists
- directory: ${cosKey} already exists
- file: ${dstPath} already exists
- Directory already exists: ${directoryAbsolutePath}
- ALERT_GROUP_EXIST
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/a7fa7fadeab9d1f5.
Report an issue: GitHub.