Firstly, many thanks for your efforts to produce a working HTTP3 module for Apache, based on the @machine-moon repository. Plus your blog post concerning PR#699 at https://codeit.guru/apache-http3-pr-699-mpm-quic-backport-2-4-68 which is most informative.
I've been looking at your 00.0.54 build on a local copy of Linux Mint 22.2, having built the various HTTPD (and its dependencies) separately from scratch (into prefix /apache24).
I'm particularly pleased your code builds against Apache HTTPD 2.4.68, rather than the current 'trunk' repository.
Using your CMake build, my log file contains the following salient details:
Building mod_http3-0.0.54 - start Tue 11 Aug 20:36:04 BST 2026
Re-run cmake no build system arguments
-- The C compiler identification is GNU 13.3.0
-- The CXX compiler identification is GNU 13.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- [nghttp3] found (1.18.0): /apache24
-- [openssl] found (3.6.3): /apache24
-- [apr] found (1.7.6): /apache24
-- [apu] found (1.6.3): /apache24
-- [httpd] found (2.4.68): /apache24
-- [ngtcp2] found (1.25.0): /apache24
--
-- Configuration Summary:
--
-- Version : 0.0.54
-- Platform : Linux-x86_64
-- Compiler : GNU (13.3.0)
-- Build Type : Release
-- BUILD_MODULE : ON
-- BUILD_EXAMPLES : OFF
-- BUILD_TESTS : OFF
--
-- ENABLE_NGTCP2 : ON
--
-- ENABLE_UBSAN : OFF
-- ENABLE_ASAN : OFF
-- ENABLE_WERROR : OFF
--
-- Configuring done (0.4s)
-- Generating done (0.0s)
-- Build files have been written to: /development/apache24/build/mod_http3
--
-- etc
--
Install the project...
/usr/bin/cmake -P cmake_install.cmake
-- Install configuration: "Release"
-- Installing: /apache24/modules/mod_http3.so
-- Set non-toolchain portion of runtime path of "/apache24/modules/mod_http3.so" to ""
-- Installing: /apache24/share/doc/mod_http3/CHANGES
-- Installing: /apache24/share/doc/mod_http3/NOTICE
-- Installing: /apache24/share/doc/mod_http3/AUTHORS
-- Installing: /apache24/share/licenses/mod_http3/LICENSE
I then followed the INSTALL document to set up a minimal local Apache server, which starts up ok. I did add the following directive to the configuration too:
LogLevel warn http3:trace8
However, the client browser isn't negotiating an HTTP3 connection as expected. Using Firefox with Developer Tools to look at the connection details, I get the following:
GET https://localhost:4433/
Status: 200 Ok
Version: HTTP/1.1
Transferred: 80.46 kB (80.01 kB size)
Request Priority: Highest
DNS Resolution: System
I know my Firefox supports HTTP3, since if I connect to https://www.google.com I get this:
GET https://www.google.com/
Status: 200
Version: HTTP/3
Transferred: 87.38 kB (284.64 kB size)
Request Priority: Highest
DNS Resolution: System
The Apache access and error logs contains the following:
root@janus:/apache24/logs# more access_log
127.0.0.1 - - [14/Aug/2026:12:27:43 +0100] "GET / HTTP/1.1" 200 191
127.0.0.1 - - [14/Aug/2026:12:27:43 +0100] "GET /favicon.ico HTTP/1.1" 404 236
root@janus:/apache24/logs# more error_log
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
[Fri Aug 14 14:27:30.255845 2026] [ssl:warn] [pid 16228:tid 16228] AH01873: Init: Session Cache is not configured [hint: SSLSessionCache]
[Fri Aug 14 14:27:30.256579 2026] [http3:info] [pid 16228:tid 16228] h3_post_config: pid=16228 cert=/apache24/common/certs/server.crt key=/apache24/common/certs/server.key h3_port=4433 mpm=event threaded=1 forked=2 max_threads=25
[Fri Aug 14 14:27:30.259276 2026] [http3:warn] [pid 16228:tid 16228] active MPM 'event' does not report externally accepted connections; graceful child shutdown may end active HTTP/3 connections early (an MPM with ap_mpm_note_extra_connection_added/_removed avoids this)
[Fri Aug 14 14:27:30.259388 2026] [http3:info] [pid 16228:tid 16228] mod_http3 loaded with version: 54 (0.0.54) on pid=16228 port=4433
[Fri Aug 14 14:27:30.259415 2026] [http3:info] [pid 16228:tid 16245] event thread started
[Fri Aug 14 14:27:42.127085 2026] [http3:info] [pid 16228:tid 16247] h3_hook_fixups called
[Fri Aug 14 14:27:42.165990 2026] [http3:info] [pid 16228:tid 16248] h3_hook_fixups called
but just occasionally after a restart I get these entries too, but the browser still reports HTTP/1.1
[Fri Aug 14 14:33:40.628941 2026] [http3:info] [pid 14748:tid 14765] accepted new QUIC connection
[Fri Aug 14 14:33:40.631772 2026] [http3:error] [pid 14748:tid 14765] QUIC handshake did not complete: peer closed the connection during the handshake
If I run my build of curl (8.21.0), built with QUIC (ngtcp2) support, against the local Apache, I get a valid HTTP3 response:
root@janus:/# /apache24/bin/curl --http3 -I -k https://localhost:4433
HTTP/3 200
alt-svc: h3=":4433"; ma=86400; persist=1
last-modified: Fri, 07 Nov 2025 08:23:08 GMT
etag: "bf-642fce432f300"
accept-ranges: bytes
content-length: 191
content-type: text/html
date: Fri, 14 Aug 2026 10:38:12 GMT
server: Apache/2.4.68 (Unix) OpenSSL/3.6.3
curl: (56) ngtcp2_conn_writev_stream returned error: ERR_CLOSING
and these additional Apache error log entries are created:
[Fri Aug 14 12:32:36.475501 2026] [http3:info] [pid 14748:tid 14765] accepted new QUIC connection
[Fri Aug 14 12:32:36.478622 2026] [http3:info] [pid 14748:tid 14765] QUIC handshake complete
[Fri Aug 14 12:32:36.479040 2026] [http3:info] [pid 14748:tid 14764] before ap_process_request
[Fri Aug 14 12:32:36.479070 2026] [http3:info] [pid 14748:tid 14764] h3_hook_access_checker called
[Fri Aug 14 12:32:36.479078 2026] [http3:info] [pid 14748:tid 14764] h3_hook_fixups called
[Fri Aug 14 12:32:36.479105 2026] [http3:info] [pid 14748:tid 14764] h3_filter_in_proto called, readbytes=8192
[Fri Aug 14 12:32:36.479109 2026] [http3:info] [pid 14748:tid 14764] serve_request_body started, h3s=
[Fri Aug 14 12:32:36.479129 2026] [http3:info] [pid 14748:tid 14764] h3_filter_out_proto: received bucket type=FILE length=191
[Fri Aug 14 12:32:36.479154 2026] [http3:info] [pid 14748:tid 14764] h3_filter_out_proto: received bucket type=EOS length=0
[Fri Aug 14 12:32:36.479162 2026] [http3:info] [pid 14748:tid 14764] h3_filter_in_proto called, readbytes=8192
[Fri Aug 14 12:32:36.479166 2026] [http3:info] [pid 14748:tid 14764] serve_request_body started, h3s=
[Fri Aug 14 12:32:36.479186 2026] [http3:info] [pid 14748:tid 14764] after ap_process_request
[Fri Aug 14 12:32:36.479336 2026] [http3:info] [pid 14748:tid 14764] queued response for stream 0, status=200, body=191
[Fri Aug 14 12:32:36.479377 2026] [http3:info] [pid 14748:tid 14765] QUIC connection terminated (idle timeout, peer close, or transport error)
[Fri Aug 14 12:32:37.368961 2026] [http3:info] [pid 14748:tid 14765] connection servicing done
So to some questions:
a) Why does the Curl request seem to work, whereas the Firefox (153.0.4) browser requests fail?
b) What's the significance of the Curl error ERR_CLOSING against the request?
c) Do you consider the NGTCP2 package a worthy option (as used by Curl HTTP3), or is the QUIC support in recent OpenSSL sufficient?
d) Your code builds against HTTPD 2.4.68, whereas @machine-moon currently needs HTTPD trunk. Is your code solution now significantly different from his, such that they might be able to build against the 2.4.x branch too? I'll probably post this question back to his repository too, but your view on the code differences would be appreciated.
e) Concerning Apache issue PR#699, if this were implemented against the 2.4.x branch, knowing UDP connections are stateless, how would added connections be removed in a timely manner? I note @covener has raised this concern in recent updates to this PR - apache/httpd#699 (review)
f) Finally, would it be possible to update your code and CMake build, to support Windows as well? I made this request to @machine-moon too, and he's responded positively. I'm going to take a look at his latest release presently, but have the frustration his code doesn't currently build against HTTPD 2.4.68.
You guys evidently have some serious programming skill; I hope between you the Apache community will soon have the option of offering a stable HTTP3 solution capable of being put into production systems.
Once again, many thanks for your efforts to date.
Firstly, many thanks for your efforts to produce a working HTTP3 module for Apache, based on the @machine-moon repository. Plus your blog post concerning PR#699 at https://codeit.guru/apache-http3-pr-699-mpm-quic-backport-2-4-68 which is most informative.
I've been looking at your 00.0.54 build on a local copy of Linux Mint 22.2, having built the various HTTPD (and its dependencies) separately from scratch (into prefix /apache24).
I'm particularly pleased your code builds against Apache HTTPD 2.4.68, rather than the current 'trunk' repository.
Using your CMake build, my log file contains the following salient details:
I then followed the INSTALL document to set up a minimal local Apache server, which starts up ok. I did add the following directive to the configuration too:
However, the client browser isn't negotiating an HTTP3 connection as expected. Using Firefox with Developer Tools to look at the connection details, I get the following:
GET https://localhost:4433/
Status: 200 Ok
Version: HTTP/1.1
Transferred: 80.46 kB (80.01 kB size)
Request Priority: Highest
DNS Resolution: System
I know my Firefox supports HTTP3, since if I connect to https://www.google.com I get this:
GET https://www.google.com/
Status: 200
Version: HTTP/3
Transferred: 87.38 kB (284.64 kB size)
Request Priority: Highest
DNS Resolution: System
The Apache access and error logs contains the following:
but just occasionally after a restart I get these entries too, but the browser still reports HTTP/1.1
If I run my build of curl (8.21.0), built with QUIC (ngtcp2) support, against the local Apache, I get a valid HTTP3 response:
and these additional Apache error log entries are created:
So to some questions:
a) Why does the Curl request seem to work, whereas the Firefox (153.0.4) browser requests fail?
b) What's the significance of the Curl error ERR_CLOSING against the request?
c) Do you consider the NGTCP2 package a worthy option (as used by Curl HTTP3), or is the QUIC support in recent OpenSSL sufficient?
d) Your code builds against HTTPD 2.4.68, whereas @machine-moon currently needs HTTPD trunk. Is your code solution now significantly different from his, such that they might be able to build against the 2.4.x branch too? I'll probably post this question back to his repository too, but your view on the code differences would be appreciated.
e) Concerning Apache issue PR#699, if this were implemented against the 2.4.x branch, knowing UDP connections are stateless, how would added connections be removed in a timely manner? I note @covener has raised this concern in recent updates to this PR - apache/httpd#699 (review)
f) Finally, would it be possible to update your code and CMake build, to support Windows as well? I made this request to @machine-moon too, and he's responded positively. I'm going to take a look at his latest release presently, but have the frustration his code doesn't currently build against HTTPD 2.4.68.
You guys evidently have some serious programming skill; I hope between you the Apache community will soon have the option of offering a stable HTTP3 solution capable of being put into production systems.
Once again, many thanks for your efforts to date.