apache/dolphinscheduler · error · ServiceException

Update the resource file from content

Error message

Update the resource file from content: {fileAbsolutePath} failed

What it means

ResourcesServiceImpl.updateFileFromContent wraps any exception thrown while persisting an updated resource file into ServiceException("Update the resource file from content: <path> failed", ex). The flow writes the new content to a local tmp file, uploads it to storage, and records metrics; a failure at any point (IO error, storage failure, closure leak) triggers this wrapped error. The tmp file is cleaned up before rethrowing.

Solutions

  1. Inspect the wrapped cause (ex) in the server log — the root exception identifies whether it's storage, IO, or configuration.
  2. Verify storage configuration (resource.storage.type and related credentials/endpoints) and connectivity from the API server.
  3. Check API server disk space and write permissions for the tmp directory, then retry the file update.

Example fix

// before: ignoring cause detail
// ServiceException("Update the resource file from content: /x.sql failed", ex)

// after: check logs for root cause and fix storage
// e.g. storage.type=s3 with expired credentials -> refresh access-key/secret-key in common.properties, retry
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-checks: disk space and storage connectivity
long usable = new File(tmpDir).getUsableSpace();
if (usable < content.length() * 2L) { throw new IllegalStateException("Insufficient disk for tmp resource write"); }

Try / catch

try {
    resourcesService.updateFileFromContent(dto);
} catch (ServiceException e) {
    // inspect e.getCause() for storage vs IO root cause; log and alert
}

Prevention

When it happens

Trigger: Editing/saving a resource file via the UI/API when the storage backend (HDFS/S3/OSS) is unreachable; local disk full or permission denied writing srcLocalTmpFileAbsolutePath; underlying StorageOperate.updateResource throws any exception.

Common situations: S3/HDFS credentials expired; resource center storage misconfigured after upgrade; disk quota exceeded on the API server node; oversized file content failing upload.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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

Appendix: source

Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ResourcesServiceImpl.java:352

                .build();
    }

    @Override
    public void updateFileFromContent(UpdateFileFromContentRequest updateFileContentRequest) {
        UpdateFileFromContentDto updateFileFromContentDto =
                updateFileFromContentRequestTransformer.transform(updateFileContentRequest);
        updateFileFromContentDtoValidator.validate(updateFileFromContentDto);

        String srcLocalTmpFileAbsolutePath = copyFileToLocal(updateFileFromContentDto.getFileContent());
        try {
            storageOperator.upload(srcLocalTmpFileAbsolutePath, updateFileFromContentDto.getFileAbsolutePath(), true,
                    true);
            ApiServerMetrics.recordApiResourceUploadSize(updateFileFromContentDto.getFileContent().length());
            log.info("Success upload resource file: {} complete.", updateFileFromContentDto.getFileAbsolutePath());
        } catch (Exception ex) {
            // If exception, clear the tmp path
            FileUtils.deleteFile(srcLocalTmpFileAbsolutePath);
            throw new ServiceException("Update the resource file from content: "
                    + updateFileFromContentDto.getFileAbsolutePath() + " failed", ex);
        }
    }

    @Override
    public void downloadResource(HttpServletResponse response, DownloadFileRequest downloadFileRequest) {
        DownloadFileDto downloadFileDto = DownloadFileDto.builder()
                .loginUser(downloadFileRequest.getLoginUser())
                .fileAbsolutePath(downloadFileRequest.getFileAbsolutePath())
                .build();
        downloadFileDtoValidator.validate(downloadFileDto);

        String fileName = new File(downloadFileDto.getFileAbsolutePath()).getName();
        String localTmpFileAbsolutePath = FileUtils.getDownloadFilename(fileName);

        try {
            storageOperator.download(downloadFileRequest.getFileAbsolutePath(), localTmpFileAbsolutePath, true);
            int length = (int) new File(localTmpFileAbsolutePath).length();

View on GitHub (pinned to 02eac45a1b)