testcontainers/testcontainers-java · warning

No explicit version tag was provided in JDBC URL and this…

Error message

No explicit version tag was provided in JDBC URL and this class ({}) does not override newInstance() to set a default tag. `latest` will be used but results may be unreliable!

What it means

When a JDBC URL like jdbc:tc:postgresql:///db omits a version tag, Testcontainers asks the matching JdbcDatabaseContainerProvider to create a container. If the provider subclass does not override the no-arg newInstance() to supply a stable default tag, the base implementation logs this warning and falls back to the floating 'latest' image tag. Because 'latest' points at whatever was most recently pushed, builds can break or behave differently over time, hence the unreliability warning.

Solutions

  1. Add an explicit version tag to the JDBC URL, e.g. jdbc:tc:postgresql:16.2:///mydb
  2. Override newInstance() in the custom JdbcDatabaseContainerProvider subclass to return newInstance("<stable-tag>")
  3. Pin a DockerImageName/image version via container-specific configuration if using the container API directly instead of the driver

Example fix

// before (provider)
public class MyDbProvider extends JdbcDatabaseContainerProvider {
    public JdbcDatabaseContainer newInstance(String tag) { return new MyDbContainer(tag); }
}
// after
public class MyDbProvider extends JdbcDatabaseContainerProvider {
    @Override
    public JdbcDatabaseContainer newInstance() { return newInstance("16.2"); }
    public JdbcDatabaseContainer newInstance(String tag) { return new MyDbContainer(tag); }
}
Defensive patterns

Strategy: validation

Validate before calling

// Prefer explicit tags in URLs
if (!jdbcUrl.matches("jdbc:tc:[^:]+:[^:]+:.*")) {
    throw new IllegalArgumentException("JDBC URL must pin an image version, e.g. jdbc:tc:postgresql:16:///db");
}

Prevention

When it happens

Trigger: Calling Driver.connect with a jdbc:tc: URL lacking a :tag segment (e.g. jdbc:tc:postgresql:16-alpine is fine, jdbc:tc:postgresql://localhost/databasename is not) where the database provider class only implements newInstance(String tag) and not newInstance().

Common situations: Upgrading testcontainers and switching to a database whose provider stopped defaulting a tag; copy-pasting a JDBC URL without an image version; CI pulls a different 'latest' image than a teammate's machine, causing flaky schema/behavior differences.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainerProvider.java:28

 */
@Slf4j
public abstract class JdbcDatabaseContainerProvider {

    /**
     * Tests if the specified database type is supported by this Container Provider. It should match to the base image name.
     * @param databaseType {@link String}
     * @return <code>true</code> when provider can handle this database type, else <code>false</code>.
     */
    public abstract boolean supports(String databaseType);

    /**
     * Instantiate a new {@link JdbcDatabaseContainer} without any specified image tag. Subclasses <i>should</i>
     * override this method if possible, to provide a default tag that is more stable than <code>latest</code>`.
     *
     * @return Instance of {@link JdbcDatabaseContainer}
     */
    public JdbcDatabaseContainer newInstance() {
        log.warn(
            "No explicit version tag was provided in JDBC URL and this class ({}) does not " +
            "override newInstance() to set a default tag. `latest` will be used but results may " +
            "be unreliable!",
            this.getClass().getCanonicalName()
        );
        return this.newInstance("latest");
    }

    /**
     * Instantiate a new {@link JdbcDatabaseContainer} with specified image tag.
     * @param tag
     * @return Instance of {@link JdbcDatabaseContainer}
     */
    public abstract JdbcDatabaseContainer newInstance(String tag);

    /**
     * Instantiate a new {@link JdbcDatabaseContainer} using information provided with {@link ConnectionUrl}.
     * @param url {@link ConnectionUrl}

View on GitHub (pinned to 8e549514e3)