{"record":{"id":"ece6a663765ce94a","repo":"grpc/grpc-java","slug":"certificate-file-not-found-or-not-readable-trus","errorCode":null,"errorMessage":"Certificate file not found or not readable: ${trustCertFile.getAbsolutePath()}","messagePattern":"Certificate file not found or not readable: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"util/src/main/java/io/grpc/util/AdvancedTlsX509TrustManager.java","lineNumber":343,"sourceCode":"        log.log(Level.SEVERE, String.format(\"Failed refreshing trust CAs from file. Using \"\n            + \"previous CAs (file lastModified = %s)\", file.lastModified()), e);\n      }\n    }\n  }\n\n  /**\n   * Reads the trust certificates specified in the path location, and updates the key store if the\n   * modified time has changed since last read.\n   *\n   * @param trustCertFile  the file on disk holding the trust certificates\n   * @param oldTime the time when the trust file is modified during last execution\n   * @return oldTime if failed or the modified time is not changed, otherwise the new modified time\n   */\n  private long readAndUpdate(File trustCertFile, long oldTime)\n      throws IOException, GeneralSecurityException {\n    long newTime = checkNotNull(trustCertFile, \"trustCertFile\").lastModified();\n    if (newTime == 0) {\n      throw new IOException(\n          \"Certificate file not found or not readable: \" + trustCertFile.getAbsolutePath());\n    }\n    if (newTime == oldTime) {\n      return oldTime;\n    }\n    FileInputStream inputStream = new FileInputStream(trustCertFile);\n    try {\n      X509Certificate[] certificates = CertificateUtils.getX509Certificates(inputStream);\n      updateTrustCredentials(certificates);\n      return newTime;\n    } finally {\n      inputStream.close();\n    }\n  }\n\n  // Mainly used to avoid throwing IO Exceptions in java.io.Closeable.\n  public interface Closeable extends java.io.Closeable {\n    @Override","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/util/src/main/java/io/grpc/util/AdvancedTlsX509TrustManager.java#L325-L361","documentation":"readAndUpdate calls File.lastModified() on the trust certificate file; a return value of 0 means the file does not exist or cannot be read (or the filesystem cannot report its mtime). The library surfaces this as an IOException naming the offending path so the caller knows which certificate file is unavailable.","triggerScenarios":"Any call path through readAndUpdate — one-shot updateTrustCredentials(File), scheduled updateTrustCredentials(File, long, TimeUnit, ScheduledExecutorService), or the periodic refresh task — when trustCertFile.lastModified() returns 0 because the path is missing, unreadable, or on a filesystem that does not expose modification times.","commonSituations":"Typo'd or relative path resolved against the wrong working directory; certificate file deleted before first use; container images built without the cert file mounted; permissions tightened after deployment; files on network mounts returning mtime 0.","solutions":["Verify the file exists at the exact absolute path (File.exists() / canRead()) before configuring the trust manager","Use an absolute path or confirm the process working directory matches the relative path assumption","Check filesystem permissions for the user running the process (and mount the cert file in containers)","If the file is rotated, do so atomically (temp file + rename) and ensure it always exists","If the file exists but lastModified() is still 0, move it to a local filesystem that reports mtimes"],"exampleFix":"// before\nFile cert = new File(\"trust.pem\"); // resolved against unknown cwd\nmanager.updateTrustCredentials(cert);\n// after\nFile cert = new File(\"/etc/app/tls/trust.pem\");\nif (!cert.exists() || !cert.canRead()) {\n  throw new FileNotFoundException(\"Trust cert missing/unreadable: \" + cert.getAbsolutePath());\n}\nmanager.updateTrustCredentials(cert);","handlingStrategy":"validation","validationCode":"File cert = new File(trustCertPath);\nif (!cert.isFile() || !cert.canRead() || cert.lastModified() == 0) {\n  throw new FileNotFoundException(\"Trust cert not found/readable: \" + cert.getAbsolutePath());\n}","typeGuard":null,"tryCatchPattern":"try {\n  manager.updateTrustCredentials(certFile);\n} catch (IOException e) {\n  if (e.getMessage().startsWith(\"Certificate file not found or not readable\")) {\n    throw new ConfigurationException(\"Fix trust cert path/permissions: \" + e.getMessage(), e);\n  }\n  throw e;\n}","preventionTips":["Use absolute paths for certificate files; never rely on process cwd","Check exists()/canRead()/lastModified() before configuring","Mount certificate files into containers and verify with the runtime user's permissions","Rotate files atomically (write temp + rename) so the file always exists","Avoid storing trust files on mounts that do not report modification times"],"tags":["file-system","tls","file-not-found","grpc"],"backgroundTag":"file-not-found","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}