apache/seatunnel · error · SeaTunnelEngineException

the uri of jar illegal

Error message

the uri of jar illegal:%s

What it means

thirdPartyJarsFromEnv converts jar URIs from the SeaTunnel env configuration into URLs. If a URI is malformed (uri.toURL throws MalformedURLException), it is wrapped in a SeaTunnelEngineException with 'the uri of jar illegal: <uri>'. This catches invalid jar path entries in env-level classpath configuration.

Solutions

  1. Fix the jar uri in the env config so it is a valid absolute URL (e.g. file:///path/to/connector.jar)
  2. Percent-encode spaces and special characters in the path, or move jars to a path without them
  3. Use an absolute path for file-based jars
  4. Print/log each uri in the env jar list and validate with new URI(...).toURL() before submitting the job

Example fix

// before
env {
  jar.urls = ["/opt/my connectors/app.jar"]
}
// after
env {
  jar.urls = ["file:///opt/my-connectors/app.jar"]
}
Defensive patterns

Strategy: validation

Validate before calling

for (String jarUri : jarUris) {
    try {
        new URI(jarUri).toURL();
    } catch (URISyntaxException | MalformedURLException | IllegalArgumentException e) {
        throw new IllegalArgumentException("Illegal jar uri: " + jarUri, e);
    }
}

Type guard

static boolean isValidJarUri(String uri) {
    try { new URI(uri).toURL(); return true; }
    catch (Exception e) { return false; }
}

Try / catch

try {
    helper.thirdPartyJarsFromEnv(envOptions);
} catch (SeaTunnelEngineException e) {
    log.error("Invalid jar uri in env config: {}", e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: Env config jar uris (e.g. seaTunnel jar dir / jar urls list) contain entries that cannot be converted to a valid URL — unsupported scheme, illegal characters like spaces or unescaped brackets, or a relative/garbage path.

Common situations: Jar paths with spaces or non-ASCII characters; missing protocol on a remote uri; pasted 'file://' with wrong number of slashes; Windows-style paths used on Linux; placeholder values not replaced in templates.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/862c8582ee0edeb6. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-engine/seatunnel-engine-core/src/main/java/org/apache/seatunnel/engine/core/parse/JobPluginClasspathHelper.java:64

    /**
     * Third-party JAR URLs declared in {@code env} ({@link EnvCommonOptions#JARS}), same as {@link
     * MultipleTableJobConfigParser#fillJobConfigAndCommonJars()} appends to common plugin jars.
     *
     * @param envOptions the env section of the job config as a {@link ReadonlyConfig}
     * @return list of resolved third-party JAR URLs (may be empty)
     */
    public static List<URL> thirdPartyJarsFromEnv(ReadonlyConfig envOptions) {
        String jarsOption = envOptions.getOptional(EnvCommonOptions.JARS).orElse("");
        return new ArrayList<>(
                Common.getThirdPartyJars(jarsOption).stream()
                        .map(Path::toUri)
                        .map(
                                uri -> {
                                    try {
                                        return uri.toURL();
                                    } catch (MalformedURLException e) {
                                        throw new SeaTunnelEngineException(
                                                "the uri of jar illegal:" + uri, e);
                                    }
                                })
                        .collect(Collectors.toList()));
    }

    /**
     * Connector JAR URLs for the given plugin configs, plus {@code commonPluginJars}, matching the
     * discovery rules used when building the pipeline:
     *
     * <ul>
     *   <li>SOURCE – {@link SeaTunnelSourcePluginDiscovery#getPluginJarAndDependencyPaths}
     *   <li>TRANSFORM – {@link SeaTunnelTransformPluginDiscovery#getPluginJarPaths}
     *   <li>SINK – {@link SeaTunnelSinkPluginDiscovery#getPluginJarAndDependencyPaths}
     * </ul>
     *
     * @param configs list of raw plugin {@link Config} blocks
     * @param type the plugin type (SOURCE, TRANSFORM, or SINK)

View on GitHub (pinned to cf67b549a7)