apache/maven · error · TransportProviderException

Unsupported remote repository

Error message

Unsupported remote repository

What it means

When DefaultTransportProvider.transport asks the resolver for a transporter, org.eclipse.aether.transporterProvider.newTransporter throws NoTransporterException if no registered transport factory supports the repository's protocol. The wrapper TransportProviderException("Unsupported remote repository") therefore means: no transport module on the classpath handles this URL scheme. Out of the box Maven supports http/https (and file/classpath only when the corresponding resolver transport modules are registered).

Source

Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultTransportProvider.java:59

    @Inject
    public DefaultTransportProvider(TransporterProvider transporterProvider) {
        this.transporterProvider = requireNonNull(transporterProvider);
    }

    @Override
    public Transport transport(Session session, RemoteRepository repository) {
        try {
            URI baseURI = new URI(repository.getUrl());
            return new DefaultTransport(
                    baseURI,
                    transporterProvider.newTransporter(
                            InternalSession.from(session).getSession(),
                            ((DefaultRemoteRepository) repository).getRepository()));
        } catch (URISyntaxException e) {
            throw new TransportProviderException("Remote repository URL invalid", e);
        } catch (NoTransporterException e) {
            throw new TransportProviderException("Unsupported remote repository", e);
        }
    }
}

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Switch the repository URL to http/https, which the default HTTP transport supports
  2. In embedded setups, register the needed transport: org.eclipse.aether:aether-transport-file / aether-transport-classpath / aether-transport-http (or a wagon provider) in the injector/container
  3. Check the URL scheme for typos and trailing garbage so it matches a registered transport

Example fix

<!-- before -->
<pluginRepositories>
  <pluginRepository>
    <id>old</id>
    <url>scp://build.example.com/m2/plugins</url>
  </pluginRepository>
</pluginRepositories>

<!-- after -->
<pluginRepositories>
  <pluginRepository>
    <id>old</id>
    <url>https://build.example.com/m2/plugins</url>
  </pluginRepository>
</pluginRepositories>
Defensive patterns

Strategy: validation

Validate before calling

static final Set<String> SUPPORTED = Set.of("http", "https", "file", "classpath"); // adjust to registered transports
String scheme = URI.create(repository.getUrl()).getScheme();
if (scheme == null || !SUPPORTED.contains(scheme.toLowerCase(Locale.ROOT))) {
    throw new IllegalArgumentException("No transport for scheme '" + scheme + "' of " + repository.getUrl());
}
transportProvider.transport(session, repository);

Try / catch

try {
    return transportProvider.transport(session, repository);
} catch (TransportProviderException e) {
    if (e.getCause() instanceof NoTransporterException) {
        // fall back to an https mirror, or register the matching transport module
        return transportProvider.transport(session, httpsMirrorOf(repository));
    }
    throw e;
}

Prevention

When it happens

Trigger: transport(session, repo) for a repository with url 'scp://...', 'svn://...', 'ftp://...', or 's3://...' with no matching provider; 'file://...' or classpath repos in a minimal embedding where aether-transport-file/classpath is not wired into the injector; http repositories when the HTTP transporter was deliberately excluded.

Common situations: Legacy poms referencing scp:// or svn:// repositories (old Codehaus/Java.net style); embedders assembling a stripped-down resolver without transport modules; scheme typos like 'htps://' that match no factory.

Related errors


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