Ktor 3.6.0 Help

HTTP/3

HTTP/3 is an HTTP protocol that runs over QUIC instead of TCP.

Ktor provides experimental HTTP/3 support with the Netty server engine.

Enable HTTP/3

HTTP/3 always uses TLS, so you need to configure at least one SSL connector.

To enable HTTP/3, call the enableHttp3() function in the Netty engine configuration:

@OptIn(ExperimentalKtorApi::class) fun main(args: Array<String>) { val keyStore = KeyStore.getInstance("JKS").apply { FileInputStream("keystore.jks").use { load(it, "foobar".toCharArray()) } } embeddedServer( Netty, configure = { sslConnector( keyStore = keyStore, keyAlias = "server", keyStorePassword = { "foobar".toCharArray() }, privateKeyPassword = { "foobar".toCharArray() } ) { host = "0.0.0.0" port = 8443 } enableHttp3() } ){ module() }.start(wait = true) }

For each SSL connector, Ktor binds an HTTP/3 endpoint to the same host and port over UDP. HTTP/1.1 and HTTP/2 continue to use TCP on that port.

Configure HTTP/3

To customize HTTP/3 and QUIC behavior, use the available options inside the enableHttp3() configuration block:

enableHttp3 { quicTokenHandler = HmacQuicTokenHandler() quicMaxIdleTimeout = 30.seconds quicInitialMaxData = 10_000_000 quicInitialMaxStreamDataBidirectionalLocal = 1_000_000 quicInitialMaxStreamDataBidirectionalRemote = 1_000_000 quicInitialMaxStreamsBidirectional = 100 udpSocketCount = 1 udpReceiveBufferSize = 0 udpSendBufferSize = 0 }

The following options are available:

quicTokenHandler

Defaults to null.

Specifies a QuicTokenHandler for QUIC address validation. Use HmacQuicTokenHandler to enable HMAC-based retry tokens.

quicMaxIdleTimeout

Defaults to 30.seconds.

Specifies how long a QUIC connection can remain idle before it is closed. Must be greater than 0.

quicInitialMaxData

Defaults to 10_000_000.

Specifies the initial value of the connection's maximum data limit. Must be greater than 0.

quicInitialMaxStreamDataBidirectionalLocal

Defaults to 1_000_000.

Specifies the initial flow-control limit for locally initiated bidirectional streams. Must be greater than 0.

quicInitialMaxStreamDataBidirectionalRemote

Defaults to 1_000_000.

Specifies the initial flow-control limit for remotely initiated bidirectional streams. Must be greater than 0.

quicInitialMaxStreamsBidirectional

Defaults to 100.

Specifies the initial number of bidirectional streams that can be opened. Must be greater than 0.

udpSocketCount

Defaults to 1.

Specifies the number of UDP sockets for the HTTP/3 endpoint. Values greater than 1 require platform support for SO_REUSEPORT.

udpReceiveBufferSize

Defaults to 0.

Specifies the UDP receive buffer (SO_RCVBUF) size in bytes. If you set 0, the operating system uses its default.

udpSendBufferSize

Defaults to 0.

Specifies the UDP send buffer (SO_SNDBUF) size in bytes. If you set 0, the operating system uses its default.

These options apply only to HTTP/3 connections and don't affect HTTP/1.1 or HTTP/2.

Configure the QUIC server codec

For advanced Netty configuration, use the configureQuicServerCodec option to customize the underlying QuicServerCodecBuilder:

enableHttp3 { configureQuicServerCodec = { // Configure the Netty QUIC server codec. } }

Use this option only when you need low-level QUIC transport configuration.

17 September 2026