apache/beam · warning
Exceptions are thrown from DoFn.teardown method when trying…
Error message
Exceptions are thrown from DoFn.teardown method when trying to discard ProcessBundleHandler
What it means
When a ProcessBundleHandler is discarded, all registered DoFn teardown functions are run in reverse order; OutOfMemoryError is rethrown, but any other Throwable from teardown is caught and this warning is logged. The bundle handler continues discarding (metrics are discarded), but user cleanup logic partially failed.
Solutions
- Fix the exception in the logged stack trace inside your @Teardown method.
- Make teardown idempotent and null-safe (check fields before use).
- Do not throw from teardown; log and swallow recoverable cleanup errors in user code.
- Release external resources in FinishBundle rather than relying solely on teardown.
Example fix
// before
@Teardown
public void teardown() {
connection.close(); // throws if never opened
}
// after
@Teardown
public void teardown() {
if (connection != null) {
try { connection.close(); } catch (Exception e) { LOG.warn("close failed", e); }
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Guard teardown state
if (connection != null && !connection.isClosed()) { /* safe to close */ } Try / catch
try {
teardown();
} catch (Exception e) {
LOG.warn("teardown failed", e); // never propagate from @Teardown
} Prevention
- Write null-safe, idempotent @Teardown methods
- Never throw from teardown; log recoverable errors
- Free heavy resources in FinishBundle so teardown is trivial
- Check logs for the underlying exception to fix user code
When it happens
Trigger: One or more DoFn.teardown() methods (via @Teardown annotated methods) throw an exception when the handler is discarded at the end of processing; only OutOfMemoryError propagates.
Common situations: Teardown closing connections that are already closed; NPEs from uninitialized fields in teardown; external resource cleanup failures during harness shutdown or invalid bundle retries.
Related errors
- Attempted to invoke timer
- Cannot access FinishBundleContext outside of @FinishBundle…
- Cannot access fire timestamp outside of @OnTimer method.
- Cannot access key as parameter outside of @OnTimer method.
- Cannot access key as parameter outside of @OnTimer method.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/9b30640de4542839.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/harness/src/main/java/org/apache/beam/fn/harness/control/ProcessBundleHandler.java:1205
getProgressRequestLock().unlock();
}
void discard() {
synchronized (this) {
this.instructionId = null;
this.cacheTokens = null;
if (this.bundleCache != null) {
this.bundleCache.clear();
}
// setupFunctions are invoked in createBundleProcessor. Invoke teardownFunction here as the
// BundleProcessor is already removed from cache and won't be re-used.
for (ThrowingRunnable teardownFunction : Lists.reverse(this.getTearDownFunctions())) {
try {
teardownFunction.run();
} catch (OutOfMemoryError oom) {
throw oom;
} catch (Throwable e) {
LOG.warn(
"Exceptions are thrown from DoFn.teardown method when trying to discard "
+ "ProcessBundleHandler",
e);
}
}
getMetricsEnvironmentStateForBundle().discard();
for (BeamFnDataOutboundAggregator aggregator : getOutboundAggregators().values()) {
aggregator.discard();
}
}
}
// this is called in cachedBundleProcessors removal listener
void shutdown() {
for (ThrowingRunnable tearDownFunction : getTearDownFunctions()) {
LOG.debug("Tearing down function {}", tearDownFunction);
try {
tearDownFunction.run();View on GitHub (pinned to 12126d8942)