apache/maven · error · IllegalArgumentException

Supplied URI is not relative

Error message

Supplied URI is not relative

What it means

Transport.get(URI relativeSource, Path target) only accepts a relative URI: the URI is resolved against the transport's baseURI (the remote repository URL) before fetching. An absolute URI (one with a scheme, so URI.isAbsolute() is true) is rejected immediately with IllegalArgumentException, because the API is designed exclusively for base-relative downloads.

Source

Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultTransport.java:50

import org.eclipse.aether.spi.connector.transport.Transporter;

import static java.util.Objects.requireNonNull;

public class DefaultTransport implements Transport {
    private final URI baseURI;
    private final Transporter transporter;

    public DefaultTransport(URI baseURI, Transporter transporter) {
        this.baseURI = requireNonNull(baseURI);
        this.transporter = requireNonNull(transporter);
    }

    @Override
    public boolean get(URI relativeSource, Path target) {
        requireNonNull(relativeSource, "relativeSource is null");
        requireNonNull(target, "target is null");
        if (relativeSource.isAbsolute()) {
            throw new IllegalArgumentException("Supplied URI is not relative");
        }
        URI source = baseURI.resolve(relativeSource);
        if (!source.toASCIIString().startsWith(baseURI.toASCIIString())) {
            throw new IllegalArgumentException("Supplied relative URI escapes baseUrl");
        }
        GetTask getTask = new GetTask(source);
        getTask.setDataPath(target);
        try {
            transporter.get(getTask);
            return true;
        } catch (Exception e) {
            if (Transporter.ERROR_NOT_FOUND != transporter.classify(e)) {
                throw new RuntimeException(e);
            }
            return false;
        }
    }

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Strip the repository base URL and pass only the remaining path, e.g. "org/apache/maven/maven-core/3.9.0/maven-core-3.9.0.jar"
  2. If you must fetch an arbitrary absolute URL, create the transport with that URL as its base via TransportProvider.transport(session, remoteRepository) instead
  3. Derive the relative URI with baseURI.relativize(absoluteURI) rather than string concatenation

Example fix

// before
URI src = URI.create("https://repo.example.com/repo/com/acme/a/1.0/a-1.0.jar");
transport.get(src, target);

// after: pass only the base-relative path
URI src = URI.create("com/acme/a/1.0/a-1.0.jar");
transport.get(src, target);
Defensive patterns

Strategy: validation

Validate before calling

URI src = ...;
if (src.isAbsolute()) {
    src = baseURI.relativize(src); // or reject: throw new IllegalArgumentException("absolute URI: " + src)
}
transport.get(src, target);

Prevention

When it happens

Trigger: Calling transport.get(URI.create("https://repo.maven.apache.org/maven2/org/foo/x.jar"), path) or any URI with a scheme such as file:/x, http://..., or a network-path reference that URI.isAbsolute() reports as absolute.

Common situations: Embedders mixing fully-qualified artifact URLs with the Transport API; code migrated from a raw HttpClient that always used absolute URLs; computing the artifact path but forgetting to strip the repository base URL.

Related errors


AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21). Data as JSON: /api/errors/6b174751cab74395. Report an issue: GitHub.