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
- 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).
- Verify which OS user the shenyu-admin process runs as (ps aux) and grant that user read access.
- In Docker, ensure the file is COPYed/owned correctly in the image rather than mounted with root-only permissions.
- 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
- Run the admin process under a user that owns (or can read) certificate/key files.
- Set explicit permissions in Dockerfile (COPY --chown) rather than relying on host ownership.
- Check canRead()/Files.isReadable() at config-load time, before first use.
- Document required permissions for mounted secrets in your deployment guide.
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
- File '' exists but is a directory
- 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/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)