apache/maven · error · IllegalArgumentException

Supplied relative URI escapes baseUrl

Error message

Supplied relative URI escapes baseUrl

What it means

After resolving the supplied relative URI against baseURI, DefaultTransport verifies the result still starts with the base URI's ASCII string. '../' sequences that navigate above the repository root produce a resolved URI outside the base and are rejected with IllegalArgumentException. This is an explicit path-traversal guard so a transport bound to one repository cannot read from another location.

Source

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

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;
        }
    }

    @Override
    public Optional<byte[]> getBytes(URI relativeSource) {
        try {
            Path tempPath = null;

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Normalize the path and strip leading parent ('..') segments so it stays under the repository root
  2. Compute relative paths with baseURI.relativize(absoluteURI) instead of manual concatenation
  3. If the artifact genuinely lives in another repository, create a separate Transport for that repository's URL

Example fix

// before
String rel = "../../infra/libs/util-1.0.jar";
transport.get(URI.create(rel), target);

// after: resolve against the other repo's own transport
Transport infra = transportProvider.transport(session, infraRepo);
infra.get(URI.create("libs/util-1.0.jar"), target);
Defensive patterns

Strategy: validation

Validate before calling

static URI safeRelative(URI base, URI rel) {
    if (rel.isAbsolute()) throw new IllegalArgumentException("absolute URI: " + rel);
    URI resolved = base.resolve(rel);
    if (!resolved.toASCIIString().startsWith(base.toASCIIString())) {
        throw new IllegalArgumentException("path escapes repository base: " + rel);
    }
    return rel;
}
transport.get(safeRelative(baseURI, rel), target);

Prevention

When it happens

Trigger: transport.get(URI.create("../../../etc/passwd"), path); transport.get(URI.create("../../other-repo/artifact.jar"), path); any relative URI whose resolution with baseURI.resolve(...) no longer starts with baseURI.toASCIIString().

Common situations: Building relative paths by string concatenation that leaves leading '../' segments; artifact coordinates containing '..' parts; deliberately probing traversal behavior in security tests.

Related errors


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