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

  1. Split the URL correctly: set url=http://host:port and sse-endpoint=/path/to/endpoint (e.g. url=http://localhost:3000, sse-endpoint=/sse).
  2. Verify the base URL includes the http:// or https:// scheme and no path portion.
  3. Check that the MCP server host/port is reachable and the endpoint path matches what the server exposes.
  4. 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

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


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/7e9559b9a4640ae8. Report an issue: GitHub.