apache/dolphinscheduler · error · CosServiceException

file: ${dstPath} already exists

Error message

file: ${dstPath} already exists

What it means

CosStorageOperator.upload throws CosServiceException when the target COS key already exists and overwrite=false. The check is done with cosClient.doesObjectExist before uploading. With overwrite=true the existing object is deleted and replaced instead.

Source

Thrown at dolphinscheduler-storage-plugin/dolphinscheduler-storage-cos/src/main/java/org/apache/dolphinscheduler/plugin/storage/cos/CosStorageOperator.java:192

        String srcCosKey = transformAbsolutePathToCOSKey(srcPath);
        String destCosKey = transformAbsolutePathToCOSKey(dstPath);
        CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, srcCosKey, bucketName, destCosKey);
        Copy copy = cosTransferManager.copy(copyObjectRequest, cosClient, null);

        CopyResult copyResult = copy.waitForCopyResult();
        if (copyResult != null && deleteSource) {
            cosClient.deleteObject(bucketName, srcPath);
        }
    }

    @SneakyThrows
    @Override
    public void upload(String srcFile, String dstPath, boolean deleteSource, boolean overwrite) {
        dstPath = transformAbsolutePathToCOSKey(dstPath);

        if (cosClient.doesObjectExist(bucketName, dstPath)) {
            if (!overwrite) {
                throw new CosServiceException("file: " + dstPath + " already exists");
            } else {
                cosClient.deleteObject(bucketName, dstPath);
            }
        }

        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, dstPath, new File(srcFile));
        Upload upload = cosTransferManager.upload(putObjectRequest);
        UploadResult uploadResult = upload.waitForUploadResult();
        if (uploadResult != null && deleteSource) {
            Files.delete(Paths.get(srcFile));
        }
    }

    @SneakyThrows
    @Override
    public List<String> fetchFileContent(String filePath, int skipLineNums, int limit) {
        String cosKey = transformAbsolutePathToCOSKey(filePath);

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Pass overwrite=true to replace the existing object
  2. Delete or rename the existing object first
  3. Upload to a versioned/unique key if the old object must be preserved

Example fix

// before
operator.upload(localFile, resourceKey, false, false);
// after
operator.upload(localFile, resourceKey, false, true); // allow replace
Defensive patterns

Strategy: try-catch

Validate before calling

if (!overwrite && operator.exists(dstKey)) { /* rename dst or ask user */ }

Try / catch

try {
    operator.upload(src, dst, deleteSource, overwrite);
} catch (CosServiceException e) {
    if (e.getMessage().contains("already exists")) {
        operator.upload(src, dst, deleteSource, true); // retry with overwrite
    } else throw e;
}

Prevention

When it happens

Trigger: Calling upload(srcFile, dstPath, deleteSource, false) when an object already exists at the transformed dstPath key.

Common situations: Re-deploying resources without enabling overwrite; two workflows concurrently uploading to the same resource key; key collision after a path rename in COS.

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/0b086f7ac95f6d05. Report an issue: GitHub.