grpc/grpc-java · error · GeneralSecurityException
Files were unmodified before their initial update. Probably
Error message
Files were unmodified before their initial update. Probably a bug.
What it means
AdvancedTlsX509KeyManager.updateIdentityCredentials (scheduling variant) performs an initial synchronous read of the cert/key files via readAndUpdate; if that initial update reports failure it throws GeneralSecurityException, since there is no usable identity material to install and periodic refreshing cannot proceed meaningfully.
Source
Thrown at util/src/main/java/io/grpc/util/AdvancedTlsX509KeyManager.java:173
* updated. You must close the returned Closeable before calling this method again or other update
* methods ({@link AdvancedTlsX509KeyManager#updateIdentityCredentials}, {@link
* AdvancedTlsX509KeyManager#updateIdentityCredentials(File, File)}).
* Before scheduling the task, the method synchronously executes {@code readAndUpdate} once. The
* minimum refresh period of 1 minute is enforced.
*
* @param certFile the file on disk holding the certificate chain
* @param keyFile the file on disk holding the private key
* @param period the period between successive read-and-update executions
* @param unit the time unit of the initialDelay and period parameters
* @param executor the executor service we use to read and update the credentials
* @return an object that caller should close when the file refreshes are not needed
*/
public Closeable updateIdentityCredentials(File certFile, File keyFile,
long period, TimeUnit unit, ScheduledExecutorService executor) throws IOException,
GeneralSecurityException {
UpdateResult newResult = readAndUpdate(certFile, keyFile, 0, 0);
if (!newResult.success) {
throw new GeneralSecurityException(
"Files were unmodified before their initial update. Probably a bug.");
}
if (checkNotNull(unit, "unit").toMinutes(period) < MINIMUM_REFRESH_PERIOD_IN_MINUTES) {
log.log(Level.FINE,
"Provided refresh period of {0} {1} is too small. Default value of {2} minute(s) "
+ "will be used.", new Object[] {period, unit.name(), MINIMUM_REFRESH_PERIOD_IN_MINUTES});
period = MINIMUM_REFRESH_PERIOD_IN_MINUTES;
unit = TimeUnit.MINUTES;
}
final ScheduledFuture<?> future =
checkNotNull(executor, "executor").scheduleWithFixedDelay(
new LoadFilePathExecution(certFile, keyFile), period, period, unit);
return () -> future.cancel(false);
}
/**
* Updates certificate chains and the private key from the local file paths.
*View on GitHub (pinned to 64daddc1f3)
Solutions
- Verify certFile and keyFile exist, are readable, and contain valid matching PEM material before calling
- Check the private key corresponds to the certificate (matching public keys)
- Ensure files are fully written/mounted before credential setup (no partial secret mounts)
- Catch GeneralSecurityException/IOException at startup and fail fast with a clear log message
Example fix
// before
km.updateIdentityCredentials(cert, key, 1, TimeUnit.HOURS, executor); // throws if files bad
// after
if (cert.exists() && key.exists()) {
km.updateIdentityCredentials(cert, key, 1, TimeUnit.HOURS, executor);
} else { log.severe("missing key material"); } Defensive patterns
Strategy: validation
Validate before calling
if (!certFile.canRead() || !keyFile.canRead() || certFile.length() == 0 || keyFile.length() == 0) { throw new IOException("Cert/key files missing or empty"); } Try / catch
try { km.updateIdentityCredentials(cert, key, period, unit, executor); } catch (GeneralSecurityException | IOException e) { /* fail fast with config diagnostics */ } Prevention
- Pre-validate cert/key files exist and parse
- Ensure secrets are mounted before startup
- Check key matches certificate
When it happens
Trigger: Calling updateIdentityCredentials(certFile, keyFile, period, unit, executor) where readAndUpdate fails on the first attempt: missing files, unreadable paths, invalid/corrupt PEM or PKCS#12 content, or wrong password/format.
Common situations: Wrong file paths in deployment config; secrets mounted late or empty; certificate format mismatch (e.g. DER vs PEM); key not matching certificate.
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
- Unsupported configurations in DownstreamTlsContext!
- Unsupported configurations in UpstreamTlsContext!
- No ALTS context information found
- Can't set TLS settings for ALTS
- Counter has overflowed.
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/89a2d4930acff57d.
Report an issue: GitHub.