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

  1. Pass overwrite=true to upload if replacing the object is intended
  2. Delete the existing object first, then upload
  3. 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

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


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/458e939f24823f27. Report an issue: GitHub.