alibaba/Sentinel · error · IllegalArgumentException
Bad file
Error message
Bad file
What it means
Thrown by the FileWritableDataSource constructor when the given File is null or is a directory. This writable data source serializes config back into a single file (e.g. for the Sentinel dashboard to persist rules), so a directory target is invalid.
Source
Thrown at sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileWritableDataSource.java:53
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private final Converter<T, String> configEncoder;
private final File file;
private final Charset charset;
private final Lock lock = new ReentrantLock(true);
public FileWritableDataSource(String filePath, Converter<T, String> configEncoder) {
this(new File(filePath), configEncoder);
}
public FileWritableDataSource(File file, Converter<T, String> configEncoder) {
this(file, configEncoder, DEFAULT_CHARSET);
}
public FileWritableDataSource(File file, Converter<T, String> configEncoder, Charset charset) {
if (file == null || file.isDirectory()) {
throw new IllegalArgumentException("Bad file");
}
if (configEncoder == null) {
throw new IllegalArgumentException("Config encoder cannot be null");
}
if (charset == null) {
throw new IllegalArgumentException("Charset cannot be null");
}
this.configEncoder = configEncoder;
this.file = file;
this.charset = charset;
}
@Override
public void write(T value) throws Exception {
lock.lock();
try {
String convertResult = configEncoder.convert(value);
FileOutputStream outputStream = null;View on GitHub (pinned to a3f40ba8e9)
Solutions
- Point the data source at a concrete file path ending in a file name (e.g. .../flow-rule.json).
- Assert the path is non-null before constructing; fail with the name of the missing property/config key.
- If the parent directory may not exist yet, create it with Files.createDirectories(parent) before writing (write() itself will fail otherwise).
Example fix
// before
new FileWritableDataSource<>("/opt/sentinel/rules/", encoder);
// after
Path p = Paths.get("/opt/sentinel/rules/flow-rule.json");
Files.createDirectories(p.getParent());
new FileWritableDataSource<>(p.toFile(), encoder); Defensive patterns
Strategy: validation
Validate before calling
if (file == null || file.isDirectory()) {
throw new IllegalArgumentException("writable rule path must be a file: " + path);
}
Files.createDirectories(file.toPath().getParent());
new FileWritableDataSource<>(file, encoder, charset); Try / catch
try {
writable = new FileWritableDataSource<>(file, encoder, charset);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Invalid FileWritableDataSource config for path: " + path, e);
} Prevention
- Always configure the full file path including file name for writable rule persistence.
- Create the parent directory at startup to avoid later write failures.
When it happens
Trigger: new FileWritableDataSource(filePath, encoder) with a path that resolves to a directory; passing a null File after a failed path lookup; using the same directory path that works for a file-based reader without appending the file name.
Common situations: Configuring rule persistence with a path like /opt/sentinel/rules/ (directory) instead of /opt/sentinel/rules/flow-rule.json; path property typo; code that builds the File conditionally and passes null on the untested branch.
Related errors
- File can't be null or a directory
- Config encoder cannot be null
- Charset cannot be null
- charset can't be null
- Bad argument: groupId=[%s], dataId=[%s]
AI-assisted analysis of alibaba/Sentinel@a3f40ba8e9 (2026-08-14).
Data as JSON: /api/errors/066ca386454b5ba2.
Report an issue: GitHub.