apache/dolphinscheduler · error · FileAlreadyExistsException
file: ${dstPath} already exists
Error message
file: ${dstPath} already exists What it means
GcsStorageOperator.upload throws FileAlreadyExistsException when the destination GCS key already exists and overwrite=false. The exists() check precedes the blob create call. With overwrite=true the blob is simply recreated with the new content.
Source
Thrown at dolphinscheduler-storage-plugin/dolphinscheduler-storage-gcs/src/main/java/org/apache/dolphinscheduler/plugin/storage/gcs/GcsStorageOperator.java:162
BlobId target = BlobId.of(bucketName, dstPath);
gcsStorage.copy(
Storage.CopyRequest.newBuilder()
.setSource(source)
.setTarget(target)
.build());
if (deleteSource) {
gcsStorage.delete(source);
}
}
@SneakyThrows
@Override
public void upload(String srcFile, String dstPath, boolean deleteSource, boolean overwrite) {
dstPath = transformAbsolutePathToGcsKey(dstPath);
if (exists(dstPath) && !overwrite) {
throw new FileAlreadyExistsException("file: " + dstPath + " already exists");
}
BlobInfo blobInfo = BlobInfo.newBuilder(
BlobId.of(bucketName, dstPath)).build();
Path srcPath = Paths.get(srcFile);
gcsStorage.create(blobInfo, Files.readAllBytes(srcPath));
if (deleteSource) {
Files.delete(srcPath);
}
}
@SneakyThrows
@Override
public List<String> fetchFileContent(String filePath, int skipLineNums, int limit) {
filePath = transformAbsolutePathToGcsKey(filePath);
if (StringUtils.isBlank(filePath)) {
log.error("file path:{} is blank", filePath);View on GitHub (pinned to 02eac45a1b)
Solutions
- Pass overwrite=true to replace the blob
- Delete the existing blob first if it is safe
- Upload to a new/unique key to keep the old object
Example fix
// before gcs.upload(localFile, resourceKey, false, false); // after gcs.upload(localFile, resourceKey, false, true);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!overwrite && gcs.exists(dstKey)) { /* rename dst or confirm overwrite */ } Try / catch
try {
gcs.upload(src, dst, deleteSource, overwrite);
} catch (FileAlreadyExistsException e) {
gcs.upload(src, dst, deleteSource, true);
} Prevention
- Set overwrite=true intentionally when replacement is expected
- Use object versioning on the bucket to preserve replaced blobs
- Avoid concurrent uploads of the same resource key
When it happens
Trigger: Calling upload(srcFile, dstPath, deleteSource, false) when a blob exists at the transformed dstPath key.
Common situations: Re-uploading a resource with overwrite disabled; concurrent uploads of the same resource key; retry after partial workflow failure leaving the blob in place.
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
- directory: ${directoryAbsolutePath} 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/e8acbe6097cf69d0.
Report an issue: GitHub.