junit-team/junit5 · error · ExtensionConfigurationException
The following TestInstanceFactory extensions were registered
Error message
The following TestInstanceFactory extensions were registered for test class [%s], but only one is permitted: %s
What it means
Thrown by ClassBasedTestDescriptor.resolveTestInstanceFactory() during the prepare() phase when the registry contains more than one TestInstanceFactory extension for a single test class. JUnit Jupiter permits at most one TestInstanceFactory per class because two factories would produce ambiguous instances, so the engine fails the entire class up front.
Source
Thrown at junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java:311
this.testInstanceFactory = null;
}
private @Nullable TestInstanceFactory resolveTestInstanceFactory(ExtensionRegistry registry) {
List<TestInstanceFactory> factories = registry.getExtensions(TestInstanceFactory.class);
if (factories.size() == 1) {
return factories.get(0);
}
if (factories.size() > 1) {
String factoryNames = factories.stream()//
.map(factory -> factory.getClass().getName())//
.collect(joining(", "));
String errorMessage = "The following TestInstanceFactory extensions were registered for test class [%s], but only one is permitted: %s".formatted(
getTestClass().getName(), factoryNames);
throw new ExtensionConfigurationException(errorMessage);
}
return null;
}
private TestInstancesProvider testInstancesProvider(JupiterEngineExecutionContext parentExecutionContext,
ClassExtensionContext ourExtensionContext) {
// For Lifecycle.PER_CLASS, ourExtensionContext.getTestInstances() is used to store the instance.
// Otherwise, extensionContext.getTestInstances() is always empty and we always create a new instance.
return (registry, context) -> ourExtensionContext.getTestInstances().orElseGet(
() -> instantiateAndPostProcessTestInstance(parentExecutionContext, ourExtensionContext, registry,
context));
}
private TestInstances instantiateAndPostProcessTestInstance(JupiterEngineExecutionContext parentExecutionContext,
ClassExtensionContext ourExtensionContext, ExtensionRegistry registry,
JupiterEngineExecutionContext context) {View on GitHub (pinned to 956246301e)
Solutions
- Read the message: it lists the offending factory class names — remove or disable all but one.
- If one factory comes from a third-party extension registered via ServiceLoader (META-INF/services/org.junit.jupiter.api.extension.Extension), exclude that class from automatic registration or do not annotate it.
- Consolidate instance creation into a single TestInstanceFactory that delegates internally if you need multiple strategies.
- Check for @ExtendWith on both a base test class and a subclass pointing at different factory classes.
Example fix
// before — two factories for one class
@ExtendWith(GuiceTestInstanceFactory.class)
class BaseTest {}
@ExtendWith(CustomTestInstanceFactory.class)
class ChildTest extends BaseTest {} // both apply -> ExtensionConfigurationException
// after — single factory, composition handled inside
@ExtendWith(GuiceTestInstanceFactory.class)
class BaseTest {}
class ChildTest extends BaseTest {} Defensive patterns
Strategy: validation
Validate before calling
// At suite setup, count TestInstanceFactory extensions for the class
List<TestInstanceFactory> factories = new ArrayList<>();
ReflectionUtils.findMethods(...) // or scan @ExtendWith on the class hierarchy
if (factories.size() > 1) throw new IllegalStateException("Duplicate TestInstanceFactory: " + factories); Prevention
- Keep at most one TestInstanceFactory per test class across the whole annotation hierarchy.
- Audit META-INF/services extension files for auto-registered factories that could collide.
- When adopting a DI test extension that ships a factory, remove any custom one you wrote.
When it happens
Trigger: Registering two TestInstanceFactory implementations for the same class via any combination of @ExtendWith on the class/meta-annotation, @RegisterExtension static fields, programmatic registration via @ExtendsWith on a base class plus a subclass, or a META-INF/services extension auto-registered globally that also implements TestInstanceFactory alongside a locally registered one.
Common situations: Mixing a test-instance-creation framework (e.g. a Mockito/Guice/Spring testinstance factory extension) with a custom factory; upgrading a library that now ships its own TestInstanceFactory that collides with yours; a ServiceLoader-registered extension that auto-applies to all classes while a @RegisterExtension also supplies one.
Related errors
- Failed to create output directory
- TestInstanceFactory [%s] failed to instantiate test class [%
- TestInstanceFactory [%s] failed to return an instance of [%s
- No ParameterResolver registered for parameter [%s] in %s [%s
- Failed to publish path
AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04).
Data as JSON: /data/errors/5b60d96fb9073921.json.
Report an issue: GitHub.