{"record":{"id":"6584503c1e75c958","repo":"apache/iceberg","slug":"interrupted-while-getting-future-results","errorCode":null,"errorMessage":"Interrupted while getting future results","messagePattern":"Interrupted while getting future results","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/util/Tasks.java","lineNumber":491,"sourceCode":"  @SuppressWarnings(\"checkstyle:CyclomaticComplexity\")\n  private static Collection<Throwable> waitFor(Collection<Future<?>> futures) {\n    while (true) {\n      int numFinished = 0;\n      for (Future<?> future : futures) {\n        if (future.isDone()) {\n          numFinished += 1;\n        }\n      }\n\n      if (numFinished == futures.size()) {\n        List<Throwable> uncaught = Lists.newArrayList();\n        // all of the futures are done, get any uncaught exceptions\n        for (Future<?> future : futures) {\n          try {\n            future.get();\n\n          } catch (InterruptedException e) {\n            LOG.warn(\"Interrupted while getting future results\", e);\n            for (Throwable t : uncaught) {\n              e.addSuppressed(t);\n            }\n            Thread.currentThread().interrupt();\n            throw new RuntimeException(e);\n\n          } catch (CancellationException e) {\n            // ignore cancellations\n\n          } catch (ExecutionException e) {\n            Throwable cause = e.getCause();\n            if (cause instanceof Error) {\n              for (Throwable t : uncaught) {\n                cause.addSuppressed(t);\n              }\n              throw (Error) cause;\n            }\n","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/util/Tasks.java#L473-L509","documentation":"Tasks.waitFor() collects results of submitted futures once all complete; future.get() was interrupted while retrieving results. The interruption flag is restored, uncaught task exceptions are attached as suppressed, and a RuntimeException wraps the InterruptedException.","triggerScenarios":"The thread running Tasks.waitFor(...) (e.g. a parallel commit/scan task driver) is interrupted while blocked in future.get() — typically by executor shutdown, task cancellation, or a parent job being cancelled (e.g. Spark/Flink job kill).","commonSituations":"Spark task cancellation during speculatively killed stages; JVM/executor shutdown while parallel file operations run; timeouts in upper layers that interrupt worker threads.","solutions":["Identify who interrupted the thread (job cancellation, executor shutdown) and avoid cancelling while critical commits run","Ensure the calling code does not shut down its executor while waitFor() is in flight","Restore and respect the interrupt flag in your own wrappers — do not swallow InterruptedException","If interruption is expected at shutdown, catch the RuntimeException and treat the operation as cancelled"],"exampleFix":"// before: shutting down pool then waiting on tasks\npool.shutdown();\nTasks.foreach(item).executeWith(pool).run();\n// after\nTasks.foreach(item).executeWith(pool).run();\npool.shutdown();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  Tasks.foreach(items).executeWith(pool).run();\n} catch (RuntimeException e) {\n  if (e.getCause() instanceof InterruptedException) {\n    Thread.currentThread().interrupt(); // restore flag; treat as cancellation\n  }\n  throw e;\n}","preventionTips":["Do not shutdownNow() executors while Tasks.waitFor() is running","Cancel jobs at safe boundaries between tasks","Never swallow InterruptedException without restoring the interrupt flag"],"tags":["java","interruption","concurrency","futures"],"backgroundTag":"invalid-state-transition","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}