eclipse-vertx/vert.x · error · SSLException
Only TLSv1.3 supported
Error message
Only TLSv1.3 supported
What it means
QuicSslContextFactory.createContext() throws SSLException when the configured enabled protocols do not include TLSv1.3. QUIC in Vert.x is built on Netty's QUIC implementation which mandates TLS 1.3; QUIC connections cannot be established with older TLS versions, so any other protocol set is rejected at context creation time.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/spi/tls/QuicSslContextFactory.java:106
public SslContext create() throws SSLException {
return createContext(forClient, kmf, tmf);
}
@Override
public SslContextFactory enabledCipherSuites(Set<String> enabledCipherSuites) {
this.enabledCipherSuites = enabledCipherSuites;
return this;
}
@Override
public SslContextFactory applicationProtocols(List<String> applicationProtocols) {
this.applicationProtocols = applicationProtocols;
return this;
}
private SslContext createContext(boolean client, KeyManagerFactory kmf, TrustManagerFactory tmf) throws SSLException {
if (!enabledProtocols.contains("TLSv1.3")) {
throw new SSLException("Only TLSv1.3 supported");
}
QuicSslContextBuilder builder;
if (client) {
builder = QuicSslContextBuilder.forClient();
if (kmf != null) {
builder.keyManager(kmf, null);
}
builder.endpointIdentificationAlgorithm(endpointIdentificationAlgorithm);
} else {
builder = QuicSslContextBuilder.forServer(kmf, null);
if (clientAuth != null) {
builder.clientAuth(clientAuth);
}
}
builder.keylog(keylog);
/*
Collection<String> cipherSuites = enabledCipherSuites;
switch (sslProvider) {View on GitHub (pinned to fb308bd8c3)
Solutions
- Ensure "TLSv1.3" is present in the enabled protocols set passed to the factory (e.g. Set.of("TLSv1.3") or add it to the existing set).
- If TLS 1.2 is a hard requirement, use a regular TCP TLS transport (e.g. HttpServerOptions/HttpClientOptions) instead of the QUIC transport.
- Remove custom protocol restrictions from the QUIC configuration and let the factory default to TLSv1.3.
Example fix
// before
factory.enabledProtocols(Set.of("TLSv1.2"));
factory.create(); // SSLException: Only TLSv1.3 supported
// after
factory.enabledProtocols(Set.of("TLSv1.3"));
factory.create(); Defensive patterns
Strategy: validation
Validate before calling
Set<String> protocols = factory /* enabledProtocols */;
if (!protocols.contains("TLSv1.3")) throw new IllegalArgumentException("QUIC requires TLSv1.3"); Type guard
boolean isQuicCompatible(Set<String> enabled) { return enabled != null && enabled.contains("TLSv1.3"); } Try / catch
try { return factory.create(); } catch (SSLException e) { if (e.getMessage().contains("Only TLSv1.3")) { /* fix protocol config */ } throw e; } Prevention
- Never restrict protocols below TLSv1.3 for QUIC/HTTP3 endpoints
- Keep QUIC TLS config separate from legacy TCP TLS config
- Validate protocol sets at startup, not lazily
When it happens
Trigger: Configuring QuicSslContextFactory with a set of enabled protocols that omits "TLSv1.3" (e.g. only TLSv1.2, or an empty/custom set) and then calling create(), which invokes createContext().
Common situations: Porting HTTP/3 or QUIC client/server options from TLS settings written for TCP endpoints; explicitly restricting protocols to TLSv1.2 for compliance on a QUIC channel; copying shared TLS config between a normal HTTPS server and a QUIC/HTTP3 server.
Related errors
- SSL configuration is necessary for a QUIC server
- Timeout must be >= 0
- http3MaxPoolSize must be > 0
- Server already bound
- Not listening
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/f217dab1e023d0c8.
Report an issue: GitHub.