apache/dolphinscheduler · error · ServiceException

file extension cannot not change

Error message

file extension cannot not change

What it means

UpdateFileDtoValidator.validate enforces that when updating a resource file, the replacement file uploaded via multipart has the same file extension as the existing resource at fileAbsolutePath. If Files.getFileExtension of the uploaded file's name differs from the extension of the target resource path, a ServiceException('file extension cannot not change') is thrown and the update is rejected. This prevents users from silently converting a resource's type (e.g. replacing a .py script with a .jar).

Source

Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/validator/resource/UpdateFileDtoValidator.java:50

@Component
public class UpdateFileDtoValidator extends AbstractResourceValidator<UpdateFileDto> {

    public UpdateFileDtoValidator(StorageOperator storageOperator, TenantDao tenantDao) {
        super(storageOperator, tenantDao);
    }

    @Override
    public void validate(UpdateFileDto updateFileDto) {
        String fileAbsolutePath = updateFileDto.getFileAbsolutePath();
        User loginUser = updateFileDto.getLoginUser();
        MultipartFile file = updateFileDto.getFile();

        if (!Objects.equals(
                Files.getFileExtension(
                        file.getOriginalFilename() == null ? file.getName() : file.getOriginalFilename()),
                Files.getFileExtension(updateFileDto.getFileAbsolutePath()))) {
            throw new ServiceException("file extension cannot not change");
        }

        exceptionResourceAbsolutePathInvalidated(fileAbsolutePath);
        exceptionResourceNotExists(fileAbsolutePath);
        exceptionResourceIsNotFile(fileAbsolutePath);
        exceptionUserNoResourcePermission(loginUser, fileAbsolutePath);
        exceptionFileInvalidated(file);
    }
}

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Re-upload a file whose name ends with the same extension as the existing resource path (match getFileExtension of fileAbsolutePath).
  2. Rename the uploaded file before the request: new File("same-name." + extensionOfTarget).
  3. If a type change is genuinely needed, delete the old resource and create a new one with the correct extension instead of updating.
  4. Ensure the HTTP client preserves the original filename in multipart Content-Disposition (set filename explicitly).

Example fix

// before: uploading replacement with mismatched name
file = new File("/tmp/script.txt"); // target resource is script.py
// after
File fixed = new File("/tmp/script.py"); // same extension as fileAbsolutePath
updateFileDto.setFile(fixed);
Defensive patterns

Strategy: validation

Validate before calling

const targetExt = filePath.split('.').pop().toLowerCase();
const uploadExt = (file.name || '').split('.').pop().toLowerCase();
if (targetExt !== uploadExt) {
  throw new Error(`Extension mismatch: target .${targetExt}, upload .${uploadExt}`);
}

Try / catch

try {
  await updateResource(dto);
} catch (e) {
  if (e.message.includes('file extension cannot not change')) {
    // surface: rename file to match resource extension and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling the resource-update API (UpdateResourceController / updateResource) with an UpdateFileDto whose uploaded MultipartFile has an original filename whose extension differs from the extension of fileAbsolutePath, e.g. updating resources/script.py with a file named script.txt.

Common situations: Renaming or re-saving a file locally before upload so the extension changes (export.csv -> export.xlsx); uploading a temp file without its extension (browser stripping .py); picking the wrong file in the UI; drag-and-drop from tools that append extensions like .download or .crdownload.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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