testcontainers/testcontainers-java · error · ScriptLoadException

Could not load classpath init script

Error message

Could not load classpath init script: ${initScriptPath}

What it means

ScriptUtils.runInitScript found the init script resource but failed to read it: an IOException occurred (e.g. in IOUtils.toString), and it wraps it in ScriptLoadException with this message. Unlike error 104, the resource exists but its content could not be loaded.

Solutions

  1. Inspect the wrapped IOException cause for the underlying I/O problem.
  2. Rebuild the project / clear stale build artifacts to fix corrupted packaged resources.
  3. Verify file read permissions on the resources directory.
  4. Confirm the resource loads in a plain unit test before using it in container setup.

Example fix

// before
URL url = getClass().getResource("/init.sql"); // from a corrupt jar
// after
// rebuild: mvn clean package, then rerun the tests
Defensive patterns

Strategy: try-catch

Validate before calling

URL url = Thread.currentThread().getContextClassLoader().getResource(initScriptPath);
try (InputStream in = url.openStream()) {
    in.readAllBytes(); // fails fast with a clear IOException if unreadable
}

Try / catch

try {
    ScriptUtils.runInitScript(delegate, initScriptPath);
} catch (ScriptLoadException e) {
    if (e.getCause() instanceof IOException) {
        // resource exists but couldn't be read: check jar integrity/permissions
    }
    throw e;
}

Prevention

When it happens

Trigger: IOUtils.toString(resource, UTF_8) throwing IOException: unreadable resource stream, underlying jar/zip corruption, or I/O failure while opening the URL connection to the classpath resource.

Common situations: Reading scripts from a fat-jar with a corrupted entry; permissions problems on the resources directory; a custom classloader returning a URL that can't be opened.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

Thrown at modules/database-commons/src/main/java/org/testcontainers/ext/ScriptUtils.java:216

     * @param initScriptPath   the resource to load the init script from
     */
    public static void runInitScript(DatabaseDelegate databaseDelegate, String initScriptPath) {
        try {
            URL resource = Thread.currentThread().getContextClassLoader().getResource(initScriptPath);
            if (resource == null) {
                resource = ScriptUtils.class.getClassLoader().getResource(initScriptPath);
                if (resource == null) {
                    LOGGER.warn("Could not load classpath init script: {}", initScriptPath);
                    throw new ScriptLoadException(
                        "Could not load classpath init script: " + initScriptPath + ". Resource not found."
                    );
                }
            }
            String scripts = IOUtils.toString(resource, StandardCharsets.UTF_8);
            executeDatabaseScript(databaseDelegate, initScriptPath, scripts);
        } catch (IOException e) {
            LOGGER.warn("Could not load classpath init script: {}", initScriptPath);
            throw new ScriptLoadException("Could not load classpath init script: " + initScriptPath, e);
        } catch (ScriptException e) {
            LOGGER.error("Error while executing init script: {}", initScriptPath, e);
            throw new UncategorizedScriptException("Error while executing init script: " + initScriptPath, e);
        }
    }

    public static void executeDatabaseScript(DatabaseDelegate databaseDelegate, String scriptPath, String script)
        throws ScriptException {
        executeDatabaseScript(
            databaseDelegate,
            scriptPath,
            script,
            false,
            false,
            DEFAULT_COMMENT_PREFIX,
            DEFAULT_STATEMENT_SEPARATOR,
            DEFAULT_BLOCK_COMMENT_START_DELIMITER,
            DEFAULT_BLOCK_COMMENT_END_DELIMITER

View on GitHub (pinned to 8e549514e3)