apache/dolphinscheduler · error · ObsException
file: ${dstPath} already exists
Error message
file: ${dstPath} already exists What it means
ObsStorageOperator.upload throws com.obs.services.ObsException when the destination key already exists in the bucket and overwrite=false. The operator explicitly checks doesObjectExist before uploading and aborts unless overwrite is true.
Source
Thrown at dolphinscheduler-storage-plugin/dolphinscheduler-storage-obs/src/main/java/org/apache/dolphinscheduler/plugin/storage/obs/ObsStorageOperator.java:156
}
@Override
public void copy(String srcPath, String dstPath, boolean deleteSource, boolean overwrite) {
srcPath = transformAbsolutePathToObsKey(srcPath);
dstPath = transformAbsolutePathToObsKey(dstPath);
obsClient.copyObject(bucketName, srcPath, bucketName, dstPath);
if (deleteSource) {
obsClient.deleteObject(bucketName, srcPath);
}
}
@SneakyThrows
@Override
public void upload(String srcFile, String dstPath, boolean deleteSource, boolean overwrite) {
dstPath = transformAbsolutePathToObsKey(dstPath);
if (obsClient.doesObjectExist(bucketName, dstPath)) {
if (!overwrite) {
throw new ObsException("file: " + dstPath + " already exists");
} else {
obsClient.deleteObject(bucketName, dstPath);
}
}
obsClient.putObject(bucketName, dstPath, new File(srcFile));
if (deleteSource) {
Files.delete(Paths.get(srcFile));
}
}
@SneakyThrows
@Override
public List<String> fetchFileContent(String filePath, int skipLineNums, int limit) {
filePath = transformAbsolutePathToObsKey(filePath);
ObsObject obsObject = obsClient.getObject(bucketName, filePath);
try (
InputStreamReader inputStreamReader = new InputStreamReader(obsObject.getObjectContent());View on GitHub (pinned to 02eac45a1b)
Solutions
- Pass overwrite=true to upload if replacing the object is intended
- Delete the existing object first, then upload
- Choose a different dstPath (versioned/timestamped key)
Example fix
// before storageOperator.upload(src, dst, false, false); // after storageOperator.upload(src, dst, false, true); // overwrite existing object
Defensive patterns
Strategy: validation
Validate before calling
boolean exists = storageOperator.existsStorageFile(dstPath); storageOperator.upload(srcFile, dstPath, deleteSource, exists ? true : overwrite);
Try / catch
try {
storageOperator.upload(src, dst, false, overwrite);
} catch (ObsException e) {
if (e.getMessage().contains("already exists")) {
storageOperator.upload(src, dst, false, true);
} else {
throw e;
}
} Prevention
- Decide overwrite semantics explicitly at every upload call site
- Prefer unique destination keys per execution over fixed paths
- Clean up leftover objects from failed runs before re-uploading
When it happens
Trigger: Calling upload(srcFile, dstPath, deleteSource, false) where an object already exists at transformAbsolutePathToObsKey(dstPath).
Common situations: Re-uploading a resource file without setting overwrite=true; a previous partially-completed upload left the object; re-running a task that uploads to a fixed destination path.
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
- file: ${dstPath} already exists
- bucketName: ${bucketName} is not exists, you need to create
- directory: ${directory} already exists
- The directory ${directoryAbsolutePath} already exists in the
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/458e939f24823f27.
Report an issue: GitHub.