apache/shenyu · error · IOException
File '' exists but is a directory
Error message
File '' exists but is a directory
What it means
HttpUtils.toBytes(File) loads a file's full contents into a byte array. Before opening the file it rejects paths that exist but are directories, because a directory cannot be read as an input stream. The error message includes the offending path.
Solutions
- Point the file path configuration at the actual regular file, not its parent directory.
- Check with Files.isRegularFile(path) before calling toBytes.
- If the path may be a directory, resolve to the intended child file explicitly.
- Handle IOException and report a clear message distinguishing 'is a directory' from 'not found'.
Example fix
// before
byte[] bytes = HttpUtils.toBytes(new File("/etc/shenyu/certs"));
// after
byte[] bytes = HttpUtils.toBytes(new File("/etc/shenyu/certs/server.pem")); Defensive patterns
Strategy: validation
Validate before calling
Path path = Paths.get(configuredPath);
if (!Files.isRegularFile(path)) {
if (Files.isDirectory(path)) throw new IllegalArgumentException("Expected a file, got directory: " + path);
throw new IllegalArgumentException("File does not exist: " + path);
} Try / catch
try {
byte[] bytes = HttpUtils.toBytes(file);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("is a directory")) {
throw new IllegalArgumentException("Configured path is a directory, expected a file: " + file, e);
}
throw e;
} Prevention
- Point config values at exact file paths, never directories.
- Use Files.isRegularFile() as a pre-check before reading.
- Resolve symlinks (toRealPath()) so a symlinked directory does not sneak through.
- Fail fast at startup if a configured file path is a directory.
When it happens
Trigger: Calling HttpUtils.toBytes with a File object whose path points at an existing directory rather than a regular file — typically a misconfigured upload path or a placeholder directory where a file was expected.
Common situations: Uploading a secret/certificate in shenyu-admin where the configured file path points to a directory (e.g. '/etc/ssl/certs' instead of a specific .pem), or a config value set to a folder name by mistake.
Related errors
- File '" + file + "' cannot be read
- File '" + file + "' does not exist
- Unable to merge from the supplied input stream
- Unable to merge from the supplied input stream
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/4547d6df86978ece.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/HttpUtils.java:738
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
while (EOF != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
}
/**
* file to bytes.
*
* @param file file
* @return byte
* @throws IOException IOException
*/
public static byte[] toBytes(final File file) throws IOException {
if (file.exists()) {
if (file.isDirectory()) {
throw new IOException("File '" + file + "' exists but is a directory");
}
if (!file.canRead()) {
throw new IOException("File '" + file + "' cannot be read");
}
} else {
throw new FileNotFoundException("File '" + file + "' does not exist");
}
InputStream input = null;
try {
input = Files.newInputStream(file.toPath());
return toBytes(input);
} finally {
try {
if (Objects.nonNull(input)) {
input.close();
}
} catch (IOException ioe) {
LOG.error("toBytes error", ioe);View on GitHub (pinned to 567142e072)