apache/shenyu · error · IOException

File '" + file + "' cannot be read

Error message

File '" + file + "' cannot be read

What it means

HttpUtils.toBytes(File) requires read permission on the file before opening it. When File.canRead() reports false it throws IOException "File '...' cannot be read", failing before an InputStream is opened.

Solutions

  1. Fix file permissions: chmod/chown so the admin process user has read access (e.g. chmod 644 for public certs, chown to the service user for keys).
  2. Verify which OS user the shenyu-admin process runs as (ps aux) and grant that user read access.
  3. In Docker, ensure the file is COPYed/owned correctly in the image rather than mounted with root-only permissions.
  4. Pre-check with Files.isReadable(path) and fail with an actionable message.

Example fix

// before (shell)
-rw------- root root /etc/shenyu/certs/server.pem
// after (shell)
chown shenyu:shenyu /etc/shenyu/certs/server.pem && chmod 400 /etc/shenyu/certs/server.pem
Defensive patterns

Strategy: validation

Validate before calling

Path path = file.toPath();
if (!Files.exists(path)) throw new FileNotFoundException("Missing file: " + path);
if (!Files.isReadable(path)) throw new AccessDeniedException("Not readable by current user: " + path);

Try / catch

try {
    byte[] bytes = HttpUtils.toBytes(file);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().contains("cannot be read")) {
        throw new IllegalStateException("Grant read permission to the shenyu-admin process user for: " + file, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling toBytes on an existing, non-directory file that the JVM process has no read permission for (OS-level ACLs, ownership by another user, or restrictive umask).

Common situations: shenyu-admin running as a non-root service account while the certificate/key/upload file was installed as root with 0600 permissions; files mounted read-only or with wrong ownership in containers.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/48d89971ea750252. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/HttpUtils.java:741

                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)