junit-team/junit5 · error · JUnitException
Failed to close extension context
Error message
Failed to close extension context
What it means
Thrown when closing the JupiterEngineExecutionContext at teardown: if the ExtensionContext implements AutoCloseable, its close() method is invoked and any Exception it raises is wrapped into a JUnitException. This surfaces failures from extension context lifecycle cleanup (closing stores, extension-scoped resources).
Solutions
- Inspect getCause() for the underlying close() exception and fix the resource's close method (close defensively, swallow/log secondary errors).
- Make your Store.CloseableResource implementations idempotent and silent on the second close.
- Use try-with-resources inside test bodies rather than relying on Store cleanup for resources that can fail.
Example fix
// before
context.getStore(NAMESPACE).put("conn", new CloseableResource() {
@Override public void close() throws Throwable { connection.close(); } // may throw
});
// after
context.getStore(NAMESPACE).put("conn", new CloseableResource() {
@Override public void close() {
try { connection.close(); } catch (SQLException e) { log.warn("close failed", e); }
}
}); Defensive patterns
Strategy: try-catch
Try / catch
try {
context.close();
} catch (JUnitException e) {
Throwable cause = e.getCause();
log.error("extension context close failed: {}", cause);
throw e;
} Prevention
- Make Store.CloseableResource.close() idempotent and swallow secondary failures.
- Use try-with-resources inside test bodies for resources that may fail to close.
- Log (do not rethrow) inside custom close implementations.
When it happens
Trigger: JupiterEngineExecutionContext.close() calls ((AutoCloseable) extensionContext).close() and the close() throws - e.g. an extension registered a CloseableResource in the Store whose close() failed, or the extension context's own cleanup (store disposal) raised.
Common situations: Extension stores a resource (file handle, DB connection, mock control) via ExtensionContext.Store.put(key, CloseableResource) and that resource's close() throws IOException; cleanup-after-failure path where the test already threw and cleanup also fails.
Related errors
- A NamespacedHierarchicalStore cannot be modified or queried…
- Failed to close custom class loader
- Failed to publish path
- Object stored under key
- Parameter resolution is disabled
AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11).
Data as JSON: /api/errors/8355948a330e650c.
Report an issue: GitHub.
Appendix: source
Thrown at junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/JupiterEngineExecutionContext.java:54
private boolean beforeAllMethodsExecuted = false;
public JupiterEngineExecutionContext(EngineExecutionListener executionListener, JupiterConfiguration configuration,
LauncherStoreFacade launcherStoreFacade) {
this(new State(executionListener, configuration, launcherStoreFacade));
}
private JupiterEngineExecutionContext(State state) {
this.state = state;
}
public void close() throws Exception {
ExtensionContext extensionContext = getExtensionContext();
if (extensionContext instanceof @SuppressWarnings("resource") AutoCloseable closeable) {
try {
closeable.close();
}
catch (Exception e) {
throw new JUnitException("Failed to close extension context", e);
}
}
}
public EngineExecutionListener getExecutionListener() {
return this.state.executionListener;
}
public JupiterConfiguration getConfiguration() {
return this.state.configuration;
}
public LauncherStoreFacade getLauncherStoreFacade() {
return this.state.launcherStoreFacade;
}
public TestInstancesProvider getTestInstancesProvider() {
return requireNonNull(this.state.testInstancesProvider);View on GitHub (pinned to f070c699a0)