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

  1. Point the file path configuration at the actual regular file, not its parent directory.
  2. Check with Files.isRegularFile(path) before calling toBytes.
  3. If the path may be a directory, resolve to the intended child file explicitly.
  4. 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

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


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)