quarkusio/quarkus · critical · SecurityException
Failed to set private key file writable by owner only. This
Error message
Failed to set private key file writable by owner only. This is a critical security requirement to protect the private key.
What it means
adjustPermissions() finishes by restricting write access to the file owner only with File.setWritable(true, true). If the OS cannot apply owner-only write permission, a SecurityException is thrown because the key must never be writable by group/others. Like the read check, it fails closed to protect key material.
Source
Thrown at extensions/tls-registry/cli/src/main/java/io/quarkus/tls/cli/letsencrypt/LetsEncryptHelpers.java:329
// Private key MUST be owner-only readable/writable (chmod 600)
if (!keyFile.setReadable(false, false)) { // Remove group/world read
LOGGER.warnf("Failed to set key file readable only by the owner: %s", keyFile.getAbsolutePath());
}
if (!keyFile.setWritable(false, false)) { // Remove group/world write
LOGGER.warnf("Failed to set key file writable only by the owner : %s", keyFile.getAbsolutePath());
}
if (!keyFile.setExecutable(false, false)) { // Remove group/world execute
LOGGER.warnf("Failed to set key file executable by owner only: %s", keyFile.getAbsolutePath());
}
// Then set owner-only permissions
if (!keyFile.setReadable(true, true)) { // Owner-only read
throw new SecurityException("Failed to set private key file readable by owner only. " +
"This is a critical security requirement to protect the private key.");
}
if (!keyFile.setWritable(true, true)) { // Owner-only write
throw new SecurityException("Failed to set private key file writable by owner only. " +
"This is a critical security requirement to protect the private key.");
}
AUDIT.debug("Set secure permissions on private key file: " + keyFile.getAbsolutePath() + " (owner-only: rw-------)");
LOGGER.debug("Set secure permissions on private key file (owner-only: rw-------)");
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Ensure the letsencrypt directory is on a writable, POSIX-capable filesystem owned by the running user
- chown/chmod the file and directory so the current user can modify permissions, then rerun
- Remount the volume read-write if it was mounted ro
- Avoid storing keys on Windows/network shares; relocate to a local directory
Example fix
// before docker run -v /etc/letsencrypt:/letsencrypt:ro ... // after docker run -v /etc/letsencrypt:/letsencrypt ... # then in container: chown -R $(id -u) /letsencrypt
Defensive patterns
Strategy: validation
Validate before calling
static boolean isWritableLocationForOwnerOnly(File dir) {
try {
File probe = File.createTempFile("permcheck", ".tmp", dir);
boolean ok = probe.setWritable(true, true) && probe.delete();
return ok;
} catch (IOException e) { return false; }
} Type guard
if (!dir.canWrite() || Files.isSymbolicLink(dir.toPath()) && !isLocalPosixFs(dir.toPath())) { chooseDifferentDirectory(); } Try / catch
try {
LetsEncryptHelpers.adjustPermissions(keyFile);
} catch (SecurityException e) {
LOGGER.error("Key file remains group/world-writable; aborting to protect key", e);
throw new IllegalStateException("Insecure key file location: " + keyFile.getParent(), e);
} Prevention
- Mount container volumes read-write and owned by the runtime user
- Avoid read-only or immutable mounts for the letsencrypt directory
- Verify with ls -l that the key ends up rw------- after runs
- Document a dedicated key directory (e.g. /var/lib/quarkus/letsencrypt) with 700 perms
When it happens
Trigger: keyFile.setWritable(true, true) returns false — the filesystem does not support POSIX write bits (Windows, FAT, some mounts), the process user does not own the file, the file is read-only at the mount level, or a SecurityManager blocks the change.
Common situations: Key stored on a read-only or immutable mount, running inside a container with a volume mounted read-only, Windows host filesystem, or the key file owned by root while the CLI runs as an unprivileged user.
Related errors
- Failed to set private key file readable by owner only. This
- No producers for required item %s, step builder used: %s
- cycle detection failure report (dynamic CycleBuildException
- Build step '%s' does not produce any build item and thus wil
- Cannot consume/produce interface or abstract class build ite
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/afc96156bc796ea3.
Report an issue: GitHub.