Spring Boot 3.4.3中Reactor Netty HttpClient未配置HTTP3却用其请求报错
Spring Boot 3.4.3升级后Unix套接字调用Docker API出现HTTP 505错误
问题现象
升级Spring Boot从3.3.9到3.4.3后,通过Unix套接字调用Docker Engine REST API的WebClient返回HTTP 505错误。日志显示请求默认使用了HTTP/3.0协议,但Docker Engine不支持该版本协议,导致版本不兼容。
相关代码
WebClient配置Bean
@Bean("dockerEngineWebClient") public WebClient dockerEngineWebClient(){ HttpClient httpClient = HttpClient.create() .remoteAddress(() -> new DomainSocketAddress("/var/run/docker.sock")) .wiretap("reactor.netty.http.client.HttpClient", LogLevel.DEBUG, AdvancedByteBufFormat.TEXTUAL); return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); }
API调用代码
public Flux<Container> listContainers() { Map<String, List<String>> parameters = Map.of("all", List.of("true")); return toFlux(get("/containers/json", parameters), Container.class); } private <T> Flux<T> toFlux(WebClient.ResponseSpec spec, Class<T> elementClass) { return spec.bodyToFlux(elementClass) .onErrorResume(e -> { log.warn("Error when calling Docker Engine API", e); return Flux.empty(); }); } private WebClient.ResponseSpec get(String path, Map<String, List<String>> parameters) { MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>(parameters); return dockerEngineWebClient.get() .uri(uriBuilder -> uriBuilder.path(path).queryParams(queryParams).build()) .retrieve(); }
日志对比
3.3.9版本成功日志
reactor.netty.http.client.HttpClient : [d25753ab] REGISTERED reactor.netty.http.client.HttpClient : [d25753ab] CONNECT: /var/run/docker.sock reactor.netty.http.client.HttpClient : [d25753ab, L: - R:/var/run/docker.sock] ACTIVE reactor.netty.http.client.HttpClient : [d25753ab-1, L: - R:/var/run/docker.sock] WRITE: 105B GET /containers/json?all=true HTTP/1.1 user-agent: ReactorNetty/1.1.27 host: localhost accept: */* reactor.netty.http.client.HttpClient : [d25753ab-1, L: - R:/var/run/docker.sock] FLUSH reactor.netty.http.client.HttpClient : [d25753ab-1, L: - R:/var/run/docker.sock] WRITE: 0B reactor.netty.http.client.HttpClient : [d25753ab-1, L: - R:/var/run/docker.sock] FLUSH reactor.netty.http.client.HttpClient : [d25753ab-1, L: - R:/var/run/docker.sock] READ: 2048B HTTP/1.1 200 OK Api-Version: 1.48 Content-Type: application/json Docker-Experimental: false Ostype: linux Server: Docker/28.0.0 (linux)
3.4.3版本错误日志
reactor.netty.http.client.HttpClient : [6481bc92] REGISTERED reactor.netty.http.client.HttpClient : [6481bc92] CONNECT: /var/run/docker.sock reactor.netty.http.client.HttpClient : [6481bc92, L: - R:/var/run/docker.sock] ACTIVE reactor.netty.http.client.HttpClient : [6481bc92-1, L: - R:/var/run/docker.sock] WRITE: 113B GET /containers/json?all=true HTTP/3.0 user-agent: ReactorNetty/1.2.4-SNAPSHOT host: localhost accept: */* reactor.netty.http.client.HttpClient : [6481bc92-1, L: - R:/var/run/docker.sock] FLUSH reactor.netty.http.client.HttpClient : [6481bc92-1, L: - R:/var/run/docker.sock] READ: 193B HTTP/1.1 505 HTTP Version Not Supported: unsupported protocol version Content-Type: text/plain; charset=utf-8 Connection: close
解决方法
问题根源是Spring Boot 3.4.x升级了Reactor Netty到1.2.x版本,该版本默认启用HTTP/3支持,对于Unix套接字这类无TLS的连接场景,Reactor Netty错误选择了HTTP/3协议。有两种解决方式:
方式一:针对特定WebClient强制指定HTTP/1.1
修改WebClient配置,在HttpClient构建时添加protocol(HttpProtocol.HTTP11):
@Bean("dockerEngineWebClient") public WebClient dockerEngineWebClient(){ HttpClient httpClient = HttpClient.create() .remoteAddress(() -> new DomainSocketAddress("/var/run/docker.sock")) .protocol(HttpProtocol.HTTP11) // 强制指定使用HTTP/1.1协议 .wiretap("reactor.netty.http.client.HttpClient", LogLevel.DEBUG, AdvancedByteBufFormat.TEXTUAL); return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); }
方式二:全局禁用HTTP/3支持
在application.properties中添加配置,全局关闭Reactor Netty的HTTP/3功能:
spring.webflux.reactor.netty.http.client.h3.enabled=false
内容的提问来源于stack exchange,提问作者Alin Tandea
相关产品推荐
相关产品推荐

