testcontainers/testcontainers-java · error · ExtensionConfigurationException
Container needs to be initialized
Error message
Container {} needs to be initialized What it means
Thrown by the JUnit Jupiter extension when a field annotated with @Container is null at the moment the extension inspects the test instance. The extension requires every container field to be assigned before lifecycle callbacks run, because it must wrap the instance in a StoreAdapter for shared lifecycle management. It is a configuration error in the test class, not a runtime/container failure.
Solutions
- Initialize the container field inline at declaration (e.g. 'static final GenericContainer<?> REDIS = new GenericContainer("redis:7")')
- If initialization must be dynamic, do it in a static initializer block or @BeforeAll that runs before the extension callback
- Verify the field is not shadowed or accidentally reset to null elsewhere in the test class
Example fix
// before
@Container
static GenericContainer<?> redis;
@BeforeAll
static void init() { redis = new GenericContainer<>("redis:7"); }
// after
@Container
static GenericContainer<?> redis = new GenericContainer<>("redis:7").withExposedPorts(6379); Defensive patterns
Strategy: validation
Validate before calling
// in test setup, before running
for (Field f : testClass.getDeclaredFields()) {
if (f.isAnnotationPresent(Container.class)) {
f.setAccessible(true);
if (f.get(null /* or instance */) == null)
throw new IllegalStateException("Field " + f.getName() + " must be initialized inline");
}
} Type guard
static boolean isInitialized(Object testInstance, Field f) throws IllegalAccessException {
f.setAccessible(true);
return f.get(testInstance) != null;
} Prevention
- Initialize @Container fields inline at declaration, ideally static final
- Never assign container fields inside @BeforeEach/@AfterEach
- Keep container creation out of conditionals
- Run tests locally before CI to catch ordering issues
When it happens
Trigger: A @Container field is declared but never initialized (stays null) when beforeEach/allCallback methods call findSharedContainers or findRestartContainers, which call getContainerInstance.
Common situations: Declaring 'static GenericContainer<?> container;' and initializing it inside a @BeforeEach method that runs after the extension reads the field; typo in initializer or conditional initialization; initialization moved to @BeforeAll but field read earlier by a parent extension.
Related errors
- FieldName: does not implement Startable
- Changing startup timeout is not supported with mode
- Unexpected scheme
- Setting a in not supported in the versions below 22.1.0
- The provided service (service) has no quota to configure
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/d77fe081f62a308e.
Report an issue: GitHub.
Appendix: source
Thrown at modules/junit-jupiter/src/main/java/org/testcontainers/junit/jupiter/TestcontainersExtension.java:250
boolean isStartable = Startable.class.isAssignableFrom(field.getType());
if (!isStartable) {
throw new ExtensionConfigurationException(
String.format("FieldName: %s does not implement Startable", field.getName())
);
}
return true;
}
return false;
};
}
private static StoreAdapter getContainerInstance(final Object testInstance, final Field field) {
try {
field.setAccessible(true);
Startable containerInstance = (Startable) field.get(testInstance);
if (containerInstance == null) {
throw new ExtensionConfigurationException("Container " + field.getName() + " needs to be initialized");
}
return new StoreAdapter(field.getDeclaringClass(), field.getName(), containerInstance);
} catch (IllegalAccessException e) {
throw new ExtensionConfigurationException("Can not access container defined in field " + field.getName());
}
}
/**
* An adapter for {@link Startable} that implement {@link CloseableResource}
* thereby letting the JUnit automatically stop containers once the current
* {@link ExtensionContext} is closed.
*/
private static class StoreAdapter implements CloseableResource, AutoCloseable {
@Getter
private String key;
private Startable container;View on GitHub (pinned to 8e549514e3)