spring-projects/spring-ai · error · IllegalArgumentException
Failed to create SSE transport for connection '<connectionNa
Error message
Failed to create SSE transport for connection '<connectionName>'. Check URL splitting: url='<baseUrl>', sse-endpoint='<sseEndpoint>'. Full URL should be split as: url=http://host:port, sse-endpoint=/path/to/endpoint
What it means
Spring AI's HttpClient-based MCP SSE client transport factory wraps any exception raised while building the SseHttpClientTransport for a named connection in this IllegalArgumentException. The message deliberately reminds the user that the MCP client connection properties split the endpoint into a base 'url' (scheme+host+port) and a separate 'sse-endpoint' path; if those are wrong (malformed URL, missing scheme, wrong split, unreachable host) builder.build() fails and this error is thrown. It chains the underlying cause for diagnosis.
Source
Thrown at auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-httpclient/src/main/java/org/springframework/ai/mcp/client/httpclient/autoconfigure/SseHttpClientTransportAutoConfiguration.java:132
if (baseUrl == null || baseUrl.trim().isEmpty()) {
throw new IllegalArgumentException("SSE connection '" + connectionName
+ "' requires a 'url' property. Example: url: http://localhost:3000");
}
try {
var transportBuilder = HttpClientSseClientTransport.builder(baseUrl)
.sseEndpoint(sseEndpoint)
.clientBuilder(HttpClient.newBuilder())
.jsonMapper(new JacksonMcpJsonMapper(jsonMapper));
for (McpClientCustomizer<HttpClientSseClientTransport.Builder> customizer : transportCustomizers) {
customizer.customize(connectionName, transportBuilder);
}
sseTransports.add(new NamedClientMcpTransport(connectionName, transportBuilder.build()));
}
catch (Exception e) {
throw new IllegalArgumentException("Failed to create SSE transport for connection '" + connectionName
+ "'. Check URL splitting: url='" + baseUrl + "', sse-endpoint='" + sseEndpoint
+ "'. Full URL should be split as: url=http://host:port, sse-endpoint=/path/to/endpoint", e);
}
}
return sseTransports;
}
}
View on GitHub (pinned to 98a7beda4f)
Solutions
- Split the URL correctly: set url=http://host:port and sse-endpoint=/path/to/endpoint (e.g. url=http://localhost:3000, sse-endpoint=/sse).
- Verify the base URL includes the http:// or https:// scheme and no path portion.
- Check that the MCP server host/port is reachable and the endpoint path matches what the server exposes.
- Inspect the chained cause exception for the precise transport failure (DNS, connection refused, URI syntax).
Example fix
// before spring.ai.mcp.client.sse.connections.weather.url=http://localhost:3000/sse // after spring.ai.mcp.client.sse.connections.weather.url=http://localhost:3000 spring.ai.mcp.client.sse.connections.weather.sse-endpoint=/sse
Defensive patterns
Strategy: validation
Validate before calling
String url = env.getProperty("spring.ai.mcp.client.sse.connections.weather.url");
String sse = env.getProperty("spring.ai.mcp.client.sse.connections.weather.sse-endpoint");
if (url == null || !url.matches("https?://[^/]+")) throw new IllegalStateException("url must be scheme://host:port with no path");
if (sse == null || !sse.startsWith("/")) throw new IllegalStateException("sse-endpoint must start with /"); Try / catch
try {
transports = sseHttpClientTransports(...);
} catch (IllegalArgumentException e) {
logger.error("MCP SSE transport failed for {}: cause={}", connName, e.getCause());
throw e;
} Prevention
- Always split MCP SSE URLs: base url without path, endpoint path in sse-endpoint.
- Smoke-test the MCP server URL with curl before wiring it into config.
- Keep connection properties in one reviewed config section to catch malformed URLs early.
When it happens
Trigger: Calling the sseHttpClientTransports @Bean method when spring.ai.mcp.client.sse.connections.<name>.url is malformed (e.g. includes the path, lacks scheme, or points to a non-resolvable host) or sse-endpoint is not a valid path, so that HttpClientTransport.Builder.build() or the customizer throws.
Common situations: Putting the full SSE endpoint URL (http://host:port/sse) into 'url' instead of splitting it into url=http://host:port and sse-endpoint=/sse; typos in the connection name properties; Docker/Kubernetes service names not resolvable from the app; trailing slashes or missing http:// scheme.
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
- SSE connection '<connectionName>' requires a 'url' property.
- MessageEndpoint must be set
- Failed to read stdio connection resource
- Multiple tools with the same name (%s)
- Multiple tools with the same name (%s)
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/7e9559b9a4640ae8.
Report an issue: GitHub.