{"record":{"id":"20cf2c61e51c04f1","repo":"alibaba/spring-cloud-alibaba","slug":"sentinel-starter-datasource-handle-file","errorCode":null,"errorMessage":"[Sentinel Starter] DataSource {} handle file [{}] error: {}","messagePattern":"\\[Sentinel Starter\\] DataSource (.+?) handle file \\[(.+?)\\] error: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/FileDataSourceProperties.java","lineNumber":95,"sourceCode":"\tpublic void setBufSize(int bufSize) {\n\t\tthis.bufSize = bufSize;\n\t}\n\n\t@Override\n\tpublic void preCheck(String dataSourceName) {\n\t\tsuper.preCheck(dataSourceName);\n\t\tString file = this.getFile();\n\t\tif (file == null) {\n\t\t\tthrow new IllegalArgumentException(\"[Sentinel Starter] DataSource \" + dataSourceName\n\t\t\t\t\t+ \" file cannot be null\");\n\t\t}\n\t\ttry {\n\t\t\tthis.setFile(\n\t\t\t\t\tResourceUtils.getFile(StringUtils.trimAllWhitespace(file))\n\t\t\t\t\t\t\t.getAbsolutePath());\n\t\t}\n\t\tcatch (IOException e) {\n\t\t\tthrow new RuntimeException(\"[Sentinel Starter] DataSource \" + dataSourceName\n\t\t\t\t\t+ \" handle file [\" + file + \"] error: \" + e.getMessage(),\n\t\t\t\t\te);\n\t\t}\n\n\t}\n\n}\n","sourceCodeStart":77,"sourceCodeEnd":103,"githubUrl":"https://github.com/alibaba/spring-cloud-alibaba/blob/115d5901102009492e05d5ec18c3f79cad4077d0/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/FileDataSourceProperties.java#L77-L103","documentation":"Thrown by FileDataSourceProperties.preCheck when ResourceUtils.getFile() fails to resolve the configured file path to a java.io.File, throwing an IOException. This RuntimeException wraps the original IOException with context including the datasource name and the problematic path. The error occurs during preCheck, which runs after the null check passes, attempting to convert the path (e.g., a classpath: or file: resource string) to an absolute filesystem path.","triggerScenarios":"Configuring a file-type Sentinel datasource with a file property value that ResourceUtils.getFile() cannot resolve. This includes: classpath resources that are inside a JAR (not on the filesystem), non-existent file: paths, malformed resource URIs, or paths with syntax errors. StringUtils.trimAllWhitespace is applied first, but the resolved path must point to an actual filesystem file.","commonSituations":"1) Using classpath:sentinel-rules.json when the resource is packaged inside a JAR and cannot be resolved as a filesystem File. 2) File path references a location that does not exist on the deployed machine. 3) The path contains a typo or wrong directory separator. 4) Running in a container where the mounted volume path differs from the configured path.","solutions":["Ensure the file path resolves to a real filesystem file — use an absolute file: path or a classpath resource that exists on disk (not inside a JAR).","Verify the file exists at the resolved path: check with ls or similar.","If the resource is inside a JAR, copy it to the filesystem at startup or use a different datasource type (e.g., Nacos, Apollo) that does not require filesystem access.","Check for typos, extra whitespace, or incorrect directory separators in the path."],"exampleFix":"# before (broken — resource inside JAR)\nspring:\n  cloud:\n    sentinel:\n      datasource:\n        ds1:\n          file:\n            file: classpath:sentinel-rules.json  # inside JAR, getFile() fails\n\n# after (fixed — absolute filesystem path)\nspring:\n  cloud:\n    sentinel:\n      datasource:\n        ds1:\n          file:\n            file: file:/opt/app/config/sentinel-rules.json","handlingStrategy":"try-catch","validationCode":"// Pre-validate that the resource resolves to a filesystem file\nimport org.springframework.util.ResourceUtils;\n\nString fileProp = props.getFile().getFile();\ntry {\n    File resolved = ResourceUtils.getFile(fileProp.trim());\n    if (!resolved.exists()) {\n        throw new IllegalStateException(\"File not found: \" + resolved.getAbsolutePath());\n    }\n} catch (IOException e) {\n    throw new IllegalStateException(\"Cannot resolve file path: \" + fileProp, e);\n}","typeGuard":null,"tryCatchPattern":"// In a custom configuration or initializer:\ntry {\n    File resolved = ResourceUtils.getFile(StringUtils.trimAllWhitespace(filePath));\n    // proceed\n} catch (IOException e) {\n    log.error(\"Cannot resolve Sentinel file datasource path: {}\", filePath, e);\n    // fall back to a known-good path or fail fast with actionable message\n    throw new IllegalStateException(\"Resolve file datasource path first: \" + filePath, e);\n}","preventionTips":["Prefer absolute filesystem paths (file:/...) over classpath: resources for file datasources to avoid JAR resolution failures.","In containerized deployments, mount config files as volumes and reference them by absolute path.","Test file resolution in the target deployment environment, not just locally."],"tags":["sentinel","file-datasource","datasource","io-error","resource-resolution"],"backgroundTag":null,"analyzedSha":"115d5901102009492e05d5ec18c3f79cad4077d0","analyzedAt":"2026-08-14T04:47:13.900Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}