{"record":{"id":"07f1d198fb4bee63","repo":"apache/iceberg","slug":"timed-out-waiting-for-eviction-executor-to-termina","errorCode":null,"errorMessage":"Timed out waiting for eviction executor to terminate","messagePattern":"Timed out waiting for eviction executor to terminate","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/apache/iceberg/rest/auth/AuthSessionCache.java","lineNumber":105,"sourceCode":"  public <T extends AuthSession> T cachedSession(String key, Function<String, T> loader) {\n    return (T) sessionCache().get(key, loader);\n  }\n\n  @Override\n  public void close() {\n    try {\n      Cache<String, AuthSession> cache = sessionCache;\n      this.sessionCache = null;\n      if (cache != null) {\n        cache.invalidateAll();\n        cache.cleanUp();\n      }\n    } finally {\n      if (executor instanceof ExecutorService) {\n        ExecutorService service = (ExecutorService) executor;\n        service.shutdown();\n        if (!Uninterruptibles.awaitTerminationUninterruptibly(service, 10, TimeUnit.SECONDS)) {\n          LOG.warn(\"Timed out waiting for eviction executor to terminate\");\n        }\n        service.shutdownNow();\n      }\n    }\n  }\n\n  @VisibleForTesting\n  Cache<String, AuthSession> sessionCache() {\n    if (sessionCache == null) {\n      synchronized (this) {\n        if (sessionCache == null) {\n          this.sessionCache = newSessionCache();\n        }\n      }\n    }\n\n    return sessionCache;\n  }","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/rest/auth/AuthSessionCache.java#L87-L123","documentation":"AuthSessionCache closes its scheduled eviction executor on close() and waits up to 10 seconds for it to terminate. If pending eviction tasks still occupy the executor's single thread after 10 seconds, this warning is logged and shutdownNow() interrupts them. It means cache cleanup did not finish gracefully, though resources are forcibly cancelled.","triggerScenarios":"Calling close() on an AuthSessionCache while the eviction executor is backed up: many cached sessions expiring at once, a blocked eviction task (e.g. a slow token revoke HTTP call in the eviction listener), or the executor thread stuck in a non-interruptible operation.","commonSituations":"REST catalog clients under heavy load with short token lifetimes; revocation endpoints that are slow or hang (network issues, proxy); JVM shutdown hooks closing the cache while eviction work is mid-flight.","solutions":["Check the eviction listener (token revoke) for slow/hanging HTTP calls and add aggressive connect/read timeouts on the OAuth client","Increase the 10s termination window if legitimate eviction work needs longer, or drain sessions before close","Avoid closing the cache concurrently with high session churn; stop traffic first","If interruption is safe, treat this as benign — shutdownNow() cancels the tasks and the JVM can proceed"],"exampleFix":"// before: eviction listener blocks close() with unbounded HTTP call\nsession -> oauthClient.revokeToken(session.token())\n// after\nsession -> {\n  oauthClient.revokeToken(session.token())\n      .timeout(Duration.ofSeconds(2))\n      .toCompletableFuture().get(2, TimeUnit.SECONDS);\n}","handlingStrategy":"fallback","validationCode":"// Before closing, ensure no pending revocations\nif (cache.estimatedSize() > 0 && revokeEndpointReachable) {\n  executor.shutdown();\n  if (!executor.awaitTermination(10, TimeUnit.SECONDS)) executor.shutdownNow();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add strict timeouts to token revocation HTTP calls in the eviction listener","Avoid closing the cache during peak session churn","Treat the warning as benign when interruption is safe at shutdown"],"tags":["java","thread-pool","shutdown","timeout"],"backgroundTag":"request-timeout","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}