testcontainers/testcontainers-java · error · ExtensionConfigurationException

Can not access container defined in field

Error message

Can not access container defined in field {}

What it means

Thrown when the extension cannot read the @Container field via reflection because field.setAccessible(true) or field.get(testInstance) raised IllegalAccessException. This happens when the JVM security model or module access rules prevent accessing the field, typically non-public fields in restricted packages or strong encapsulation (JPMS) blocking reflection.

Solutions

  1. Make the container field public (or at least accessible) and public static for @Container static fields
  2. Add JVM args like --add-opens <module>/<package>=ALL-UNNAMED for the declaring package
  3. If using JPMS, add 'opens <package>;' to the module-info of the test classes
  4. Check that the field's declaring class is actually loaded from the test classpath, not a duplicate class in another classloader

Example fix

// before
@Container
private GenericContainer<?> redis = new GenericContainer<>("redis:7");

// after
@Container
public GenericContainer<?> redis = new GenericContainer<>("redis:7");
// or run tests with: --add-opens com.example.tests/com.example.tests=ALL-UNNAMED
Defensive patterns

Strategy: validation

Validate before calling

// check the field is reflective-accessible before the test runs
Field f = testClass.getDeclaredField("redis");
try { f.setAccessible(true); }
catch (InaccessibleObjectException e) { throw new IllegalStateException("Add --add-opens for " + f.getDeclaringClass().getPackageName(), e); }

Try / catch

try {
  extension.processContainers(...);
} catch (ExtensionConfigurationException e) {
  if (e.getMessage().startsWith("Can not access container")) {
    // add --add-opens or make the field public, then re-run
  }
  throw e;
}

Prevention

When it happens

Trigger: getContainerInstance calls field.setAccessible(true)/field.get(testInstance) on a field whose declaring class/package is not open to the testcontainers extension, and IllegalAccessException is rethrown as ExtensionConfigurationException.

Common situations: Container fields declared private in a named module that does not open the package; running on JDK 16+ with strong encapsulation and no --add-opens; security manager or native-image restricting reflection; fields on a superclass in a different non-opened package.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12). Data as JSON: /api/errors/6cf4338cb0ebadf5. Report an issue: GitHub.

Appendix: source

Thrown at modules/junit-jupiter/src/main/java/org/testcontainers/junit/jupiter/TestcontainersExtension.java:254

                        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;

        private StoreAdapter(Class<?> declaringClass, String fieldName, Startable container) {
            this.key = declaringClass.getName() + "." + fieldName;
            this.container = container;

View on GitHub (pinned to 8e549514e3)