{"record":{"id":"85b7f70a35f84e49","repo":"apache/dolphinscheduler","slug":"the-file-type-fileextension-cannot-be-fetched","errorCode":null,"errorMessage":"The file type: ${fileExtension} cannot be fetched","messagePattern":"The file type: (.+?) cannot be fetched","errorType":"validation","errorClass":"ServiceException","httpStatus":null,"severity":"warning","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/validator/resource/AbstractResourceValidator.java","lineNumber":83,"sourceCode":"        }\n    }\n\n    public void exceptionFileInvalidated(MultipartFile file) {\n        if (file == null) {\n            throw new ServiceException(\"The file is null\");\n        }\n    }\n\n    public void exceptionFileContentInvalidated(String fileContent) {\n        if (StringUtils.isEmpty(fileContent)) {\n            throw new ServiceException(\"The file content is null\");\n        }\n    }\n\n    public void exceptionFileContentCannotFetch(String fileAbsolutePath) {\n        String fileExtension = Files.getFileExtension(fileAbsolutePath);\n        if (!FILE_SUFFIXES_WHICH_CAN_FETCH_CONTENT.contains(fileExtension)) {\n            throw new ServiceException(\"The file type: \" + fileExtension + \" cannot be fetched\");\n        }\n    }\n\n    public void exceptionResourceNotExists(String resourceAbsolutePath) {\n        if (!storageOperator.exists(resourceAbsolutePath)) {\n            throw new ServiceException(\"Thr resource is not exists: \" + resourceAbsolutePath);\n        }\n    }\n\n    public void exceptionResourceExists(String resourceAbsolutePath) {\n        if (storageOperator.exists(resourceAbsolutePath)) {\n            throw new ServiceException(\"The resource is already exist: \" + resourceAbsolutePath);\n        }\n    }\n\n    public void exceptionResourceIsNotDirectory(String resourceAbsolutePath) {\n        if (StringUtils.isNotEmpty(Files.getFileExtension(resourceAbsolutePath))) {\n            throw new ServiceException(\"The path is not a directory: \" + resourceAbsolutePath);","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/validator/resource/AbstractResourceValidator.java#L65-L101","documentation":"exceptionFileContentCannotFetch checks the extension of the requested file against FILE_SUFFIXES_WHICH_CAN_FETCH_CONTENT (a whitelist of text-like suffixes such as .sql, .sh, .py, .txt). If the extension is not in the whitelist, viewing the file's content via the API is refused with ServiceException(\"The file type: {ext} cannot be fetched\"), because binary files cannot be rendered as text.","triggerScenarios":"Calling the 'view resource content' endpoint for a binary file (e.g. .jar, .zip, .xlsx, .tar.gz) or a file with an unusual/missing extension.","commonSituations":"User clicks 'view' in the resource center on an uploaded jar/zip; extension uppercase or non-standard (e.g. .SQL vs .sql) not matching the whitelist; uploading files whose extension was changed after creation.","solutions":["Download the file instead of fetching inline content for binary types (jar, zip, images, etc.).","Rename/convert the file to a whitelisted text extension if it truly is text (and re-upload if needed).","If a new text type is legitimately needed, add its extension to FILE_SUFFIXES_WHICH_CAN_FETCH_CONTENT in the source and redeploy."],"exampleFix":"// before\nGET /resources/view?path=/alice/resources/app.jar   // binary\n// after\nGET /resources/download?path=/alice/resources/app.jar  // or view a .sql/.sh/.py file instead","handlingStrategy":"validation","validationCode":"// client-side pre-check against the server whitelist\nconst viewable = ['.sh', '.bat', '.sql', '.py', '.txt', '.md', '.properties', '.yml', '.yaml', '.json', '.xml'];\nif (!viewable.includes(extension.toLowerCase())) {\n    // use the download endpoint instead of view-content\n}","typeGuard":"function isViewableTextFile(fileName) {\n  const ext = fileName.slice(fileName.lastIndexOf('.') + 1).toLowerCase();\n  return ['.sql', '.sh', '.py', '.txt', '.md', '.yml', '.yaml', '.json', '.xml', '.properties'].includes('.' + ext);\n}","tryCatchPattern":"try {\n    // view resource content\n} catch (ServiceException e) {\n    if (e.getMessage().startsWith(\"The file type:\")) {\n        // fall back to the download endpoint for this file\n    } else throw e;\n}","preventionTips":["Show the 'view content' action only for whitelisted text extensions in the UI","Keep file extensions consistent (lowercase, standard) when uploading","Use download for binary files (jar, zip, images) instead of content fetch"],"tags":["resource","file-type","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}