mod_http3 httpd Configuration¶
Apache httpd configuration directives for mod_http3.
For build and installation, see INSTALL.
Overview¶
mod_http3 enables HTTP/3 protocol support in Apache HTTP Server. The module:
- Creates a separate worker thread for HTTP/3 connections over UDP/QUIC
- Uses OpenSSL for QUIC/TLS 1.3 support
- Uses nghttp3 for HTTP/3 protocol handling
- Integrates with Apache's standard request processing pipeline
Configuration Directives¶
H3CertificatePath¶
Syntax: H3CertificatePath /path/to/certificate.pem
Context: server config, virtual host
Required: Yes
Path to the TLS certificate file for HTTP/3 connections. May point to the same file used by SSLCertificateFile.
H3CertificateKeyPath¶
Syntax: H3CertificateKeyPath /path/to/private-key.pem
Context: server config, virtual host
Required: Yes
Path to the TLS private key file for HTTP/3 connections. May point to the same file used by SSLCertificateKeyFile.
H3Port¶
Syntax: H3Port port
Context: server config, virtual host
Default: the port of the VirtualHost that configured HTTP/3
UDP port the QUIC listener binds to. When unset, the module reuses the port of the VirtualHost that carries the H3CertificatePath/H3CertificateKeyPath pair, so TCP (HTTP/1.1, HTTP/2) and UDP (HTTP/3) share the same port number. Set it explicitly to serve HTTP/3 on a different port.
H3MaxConcurrentStreams¶
Syntax: H3MaxConcurrentStreams n
Context: server config, virtual host
Default: 100
Maximum number of concurrent HTTP/3 streams (in-flight requests) per QUIC connection.
H3MaxConnections¶
Syntax: H3MaxConnections n
Context: server config, virtual host
Default: 256
Maximum number of concurrent QUIC/HTTP/3 connections per child process. New connection attempts beyond the limit are refused.
H3StreamBufferSize¶
Syntax: H3StreamBufferSize bytes
Context: server config, virtual host
Default: 65536
Per-stream request and streaming-response buffer size in bytes. For responses, this bounds the producer/consumer queue between Apache request workers and the QUIC event thread; a full queue applies backpressure to the request worker.
H3MaxRequestBodySize¶
Syntax: H3MaxRequestBodySize bytes
Context: server config, virtual host
Default: 10485760 (10 MiB)
Maximum HTTP/3 request body size in bytes. Request bodies are fully buffered in memory; requests exceeding the limit are rejected.
H3MaxResponseBodySize¶
Syntax: H3MaxResponseBodySize bytes
Context: server config, virtual host
Default: unlimited
Maximum HTTP/3 response body size in bytes. By default, responses stream through
the bounded queue controlled by H3StreamBufferSize and are not retained in
full. Setting an explicit finite limit switches that virtual host to bounded
whole-response buffering, allowing an over-limit response to be replaced with
a 500 Internal Server Error before its headers or partial body are sent.
H3AltSvc¶
Syntax: H3AltSvc on|off
Context: server config, virtual host
Default: on
Whether to advertise HTTP/3 support by injecting an Alt-Svc response header. This is how browsers and other TCP clients discover that HTTP/3 is available over UDP. See Alt-Svc Header.
H3AltSvcMaxAge¶
Syntax: H3AltSvcMaxAge seconds
Context: server config, virtual host
Default: 86400
Number of seconds a client may cache the Alt-Svc HTTP/3 advertisement (the ma= field of the injected header).
H3HandshakeTimeout¶
Syntax: H3HandshakeTimeout seconds
Context: server config, virtual host
Default: 10
The timeout duration in seconds for QUIC handshakes to complete. If a connection is accepted but fails to finish the cryptographic TLS/QUIC handshake within this period, it is terminated and its resources are cleaned up. Helps prevent resource exhaustion attacks.
H3IdleTimeout¶
Syntax: H3IdleTimeout seconds
Context: server config, virtual host
Default: 300
The idle timeout duration in seconds for QUIC connections. This maps to the standard QUIC max_idle_timeout transport parameter. A connection will be closed if no traffic is sent or received within this timeframe. Use a higher value for applications that require long-lived idle connections (e.g., long-polling, WebSockets over HTTP/3).
H3AddressValidation¶
Syntax: H3AddressValidation on|off
Context: server config, virtual host
Default: on
Whether to validate a client's source address before accepting a connection. When on, the server answers each new connection with a QUIC Retry packet (RFC 9000 section 8.1.2) and completes the handshake only after the client echoes the token back, which proves the client can receive at the address it claims. This is the defence against address-spoofed amplification attacks.
Turning it off removes one round trip from every connection, at the cost of that protection. Leave it on for internet-facing deployments. It exists mainly for interoperability testing, where a test may require a handshake that completes without an intervening Retry.
H3QuicEngine¶
Syntax: H3QuicEngine openssl|ngtcp2|null
Context: server config, virtual host
Default: openssl
Which QUIC transport carries HTTP/3. openssl uses OpenSSL 3.5's own QUIC implementation and is always available. ngtcp2 is present only when the module was built with -DENABLE_NGTCP2=ON; naming an engine the build does not contain is a fatal configuration error, so httpd refuses to start rather than quietly serving on the other one. OpenSSL provides TLS on both paths, so there is only ever one TLS stack in the process.
null implements the whole engine contract and carries no traffic: the server
listens but never completes a handshake. It exists to keep the contract
addable-to and to run the module with no transport underneath; do not select it
in production.
Naming an engine this build does not contain is rejected when the configuration
is parsed, so httpd -t catches it and names the engines that are compiled in.
The engine in use is reported by the http3-status handler as quic_backend.
That handler is not mapped anywhere by default; give it a location first:
VirtualHost Configuration¶
Port Detection¶
The module automatically detects the port from the VirtualHost configuration:
# HTTP/3 will listen on port 8443
<VirtualHost *:8443>
ServerName secure.example.com
H3CertificatePath /etc/httpd/ssl/secure.crt
H3CertificateKeyPath /etc/httpd/ssl/secure.key
</VirtualHost>
Use H3Port to bind the QUIC listener to a different UDP port than the VirtualHost's TCP port.
Multiple VirtualHosts¶
The module uses the first VirtualHost that has both H3CertificatePath and H3CertificateKeyPath configured:
# This VirtualHost is used for HTTP/3
<VirtualHost *:4433>
ServerName primary.example.com
H3CertificatePath /etc/httpd/ssl/primary.crt
H3CertificateKeyPath /etc/httpd/ssl/primary.key
</VirtualHost>
# This VirtualHost is ignored for HTTP/3
<VirtualHost *:4433>
ServerName secondary.example.com
H3CertificatePath /etc/httpd/ssl/secondary.crt
H3CertificateKeyPath /etc/httpd/ssl/secondary.key
</VirtualHost>
Alt-Svc Header¶
mod_http3 injects the Alt-Svc response header automatically when HTTP/3 is configured (controlled by H3AltSvc, on by default):
| Field | Meaning |
|---|---|
h3=":4433" |
HTTP/3 available on same host, on the H3Port |
ma=86400 |
Advertise for H3AltSvcMaxAge seconds |
persist=1 |
Persist across network changes |
To customize the header beyond H3AltSvcMaxAge, set it manually via mod_headers; the module does not overwrite an already-present Alt-Svc header:
Disable the advertisement entirely with H3AltSvc off.
EnableMMAP¶
EnableMMAP is fully supported. The output filter accepts and processes both raw file and memory-mapped (MMAP) data buckets transparently.
Troubleshooting¶
Startup Validation¶
The module validates configuration during Apache startup:
- Certificate Path Check:
H3CertificatePathis configured - Key Path Check:
H3CertificateKeyPathis configured
If either check fails, Apache refuses to start.
Testing Configuration¶
Verifying HTTP/3 Operation¶
ss -ulnp | grep httpd # check UDP listener
curl --http3 -k https://localhost:4433/ # test transfer
tail -f /var/log/httpd/error_log # watch logs
Debug Logging¶
Log Messages¶
# Successful configuration
h3_post_config: pid=[PID] cert=/path/to/cert key=/path/to/key h3_port=443 mpm=event threaded=1 forked=2 max_threads=25
# Worker thread started
h3_child_init
worker_thread_main
# Errors
mod_http3: H3CertificatePath directive is required but not configured
mod_http3: H3CertificateKeyPath directive is required but not configured