apache/iceberg · error · RuntimeException

Task set failed with an uncaught throwable

Error message

Task set failed with an uncaught throwable

What it means

Tasks (single-threaded execution path) collects task failures; if a task threw a Throwable that is not an Exception (so it escaped the exception-collection logic, caught via 'threw'), and throwFailureWhenFinished is set and the exceptions list is empty, it throws this RuntimeException. It signals a non-Exception throwable (e.g. Error, or a Throwable subclass) killed the task set without being recorded as a normal failure.

Solutions

  1. Inspect the task's original stack trace/logs — this wrapper hides a non-Exception throwable; find the underlying Error
  2. Fix the root cause (classpath, memory, or bad throwable usage in task code)
  3. Ensure task code throws Exception/RuntimeException subtypes so failures are collected and reported via throwOne
  4. If failures should be tolerated, drop throwFailureWhenFinished or add .suppress()/.retry() configuration

Example fix

// before
Tasks.foreach(items).throwFailureWhenFinished().run(item -> process(item)); // process throws Error
// after
Tasks.foreach(items).throwFailureWhenFinished().run(item -> {
  try { process(item); } catch (Throwable t) {
    throw new RuntimeException("processing failed for " + item, t); // surface as collected failure
  }
});
Defensive patterns

Strategy: try-catch

Try / catch

boolean ok = Tasks.foreach(items)
  .suppress()
  .run(task);
if (!ok) { /* inspect logs for the non-Exception throwable */ }

Prevention

When it happens

Trigger: Running Tasks.foreach(...).throwFailureWhenFinished() where a task threw a Throwable that is not an Exception (e.g. StackOverflowError, NoClassDefFoundError, or a custom Throwable), bypassing the exceptions list.

Common situations: Classpath issues surfacing as Error during task execution; OOM/stack overflow inside task bodies; throwing Throwable subclasses from custom task implementations.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/bf633819877e9b2b. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/util/Tasks.java:278

              try {
                abortTask.run(iterator.next());
              } catch (Exception e) {
                failed = true;
                LOG.error("Failed to abort task", e);
                // keep going
              }
              if (stopAbortsOnFailure && failed) {
                break;
              }
            }
          }
        }
      }

      if (throwFailureWhenFinished && !exceptions.isEmpty()) {
        Tasks.throwOne(exceptions, exceptionClass);
      } else if (throwFailureWhenFinished && threw) {
        throw new RuntimeException("Task set failed with an uncaught throwable");
      }

      return !threw;
    }

    private void tryRunOnFailure(I item, Exception failure) {
      try {
        onFailure.run(item, failure);
      } catch (Exception failException) {
        failure.addSuppressed(failException);
        LOG.error("Failed to clean up on failure", failException);
        // keep going
      }
    }

    private <E extends Exception> boolean runParallel(
        final Task<I, E> task, Class<E> exceptionClass) throws E {
      final Queue<I> succeeded = new ConcurrentLinkedQueue<>();

View on GitHub (pinned to 86d9c8fc54)