quarkusio/quarkus · error · RuntimeException
Failure to save the account
Error message
Failure to save the account
What it means
saveAccount persists the ACME account JSON to <letsEncryptPath>/account.json via Files.copy with REPLACE_EXISTING. Any IOException while writing (bad directory, permissions, disk full) is wrapped in this RuntimeException. Without the account file, later certificate operations cannot authenticate.
Source
Thrown at extensions/tls-registry/cli/src/main/java/io/quarkus/tls/cli/letsencrypt/LetsEncryptHelpers.java:168
if (acmeAccount.getKeyAlgorithmName() != null) {
json.put("key-algorithm", acmeAccount.getKeyAlgorithmName());
}
json.put("key-size", acmeAccount.getKeySize());
return json;
}
private static void saveAccount(String letsEncryptPath, JsonObject accountJson) {
LOGGER.debugf("Saving account to %s", letsEncryptPath);
// If more than one account must be supported, we can save accounts to unique files in .lets-encrypt/accounts
// and require an account alias/id during operations requiring an account
java.nio.file.Path accountPath = Paths.get(letsEncryptPath + "/account.json");
try {
AUDIT.debug("Writing ACME account to file: " + accountPath.toString());
Files.copy(new ByteArrayInputStream(accountJson.encode().getBytes(StandardCharsets.US_ASCII)), accountPath,
StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
throw new RuntimeException("Failure to save the account", ex);
}
}
public static void issueCertificate(
AcmeClient acmeClient,
File letsEncryptPath,
boolean staging,
String domain,
File certChainPemLoc,
File privateKeyPemLoc,
String acmeServerUrl,
String acmeStagingServerUrl) {
AcmeAccount acmeAccount = getAccount(letsEncryptPath, acmeServerUrl, acmeStagingServerUrl);
AUDIT.info("Requesting certificate - domain: " + domain + ", staging: " + staging + ", server: "
+ (acmeServerUrl != null ? acmeServerUrl : "default"));
X509CertificateChainAndSigningKey certChainAndPrivateKey;View on GitHub (pinned to e1c734241f)
Solutions
- Ensure the letsEncrypt directory exists before creating the account: mkdir -p <letsencrypt-dir>
- Check write permissions on the directory (and run as a user with access)
- Verify the filesystem is not read-only or full (df -h, mount options)
- If the error persists, inspect the wrapped cause ('Caused by' IOException) for the exact filesystem failure
Example fix
// before
LetsEncryptHelpers.createAccount(acmeClient, new File("/nonexistent/letsencrypt"), termsAgreed, ...); // RuntimeException
// after
File dir = new File("/etc/quarkus/letsencrypt");
dir.mkdirs();
LetsEncryptHelpers.createAccount(acmeClient, dir, termsAgreed, ...); Defensive patterns
Strategy: validation
Validate before calling
File dir = letsEncryptPath;
if (!dir.exists() || !dir.isDirectory()) {
dir.mkdirs();
}
if (!dir.canWrite()) {
throw new IllegalStateException("Directory not writable: " + dir);
}
LetsEncryptHelpers.createAccount(acmeClient, dir, termsAgreed, email); Try / catch
try {
LetsEncryptHelpers.createAccount(acmeClient, letsEncryptDir, termsAgreed, email);
} catch (RuntimeException e) {
if (e.getCause() instanceof IOException) {
throw new IllegalStateException("Cannot write ACME account to " + letsEncryptDir + ": " + e.getCause().getMessage(), e);
}
throw e;
} Prevention
- Create the letsencrypt directory (with mkdirs) before account creation
- Run the CLI/container as a user with write access to the config directory
- Mount persistent writable volumes when running in containers
- Monitor disk space on hosts writing certificates
When it happens
Trigger: Calling createAccount (which calls saveAccount) when letsEncryptPath does not exist or is not writable — e.g. directory missing, read-only filesystem, or insufficient file permissions.
Common situations: Running the CLI as a user without write access to the config directory; letsencrypt directory not created beforehand; running in a container with a read-only filesystem; disk full on the host.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
Related errors
- Unable to read the account file, you must create account fir
- Failed to create output directory for generated sources: %s
- IOException (wrapped)
- Unable to validate the application root for remote-dev path:
- Unable to validate remote-dev path: <file>
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/322a51ec94c80c92.
Report an issue: GitHub.