caddyserver/caddy · critical
starting HTTP/3 QUIC listener: %v
Error message
starting HTTP/3 QUIC listener: %v
What it means
serveHTTP3 resolves the QUIC-equivalent network for the listener's network string via getHTTP3Network before opening the QUIC listener; this wrapper fires when that mapping is missing — i.e. the configured network type has no HTTP/3 counterpart registered. The wrapped error is "network '%s' cannot handle HTTP/3 connections".
Source
Thrown at modules/caddyhttp/server.go:942
}
// If we didn't actually find a host matcher, return 0
// because that means every defined route was a "catch-all".
// See https://caddy.community/t/how-to-set-priority-in-caddyfile/13002/8
if !foundHostMatcher {
return 0
}
return lastIndex
}
// serveHTTP3 creates a QUIC listener, configures an HTTP/3 server if
// not already done, and then uses that server to serve HTTP/3 over
// the listener, with Server s as the handler.
func (s *Server) serveHTTP3(addr caddy.NetworkAddress, tlsCfg *tls.Config) error {
h3net, err := getHTTP3Network(addr.Network)
if err != nil {
return fmt.Errorf("starting HTTP/3 QUIC listener: %v", err)
}
addr.Network = h3net
h3ln, err := addr.ListenQUIC(s.ctx, 0, net.ListenConfig{}, tlsCfg, s.packetConnWrappers, s.Allow0RTT)
if err != nil {
return fmt.Errorf("starting HTTP/3 QUIC listener: %v", err)
}
// create HTTP/3 server if not done already
if s.h3server == nil {
s.h3server = &http3.Server{
Handler: s,
TLSConfig: tlsCfg,
MaxHeaderBytes: s.MaxHeaderBytes,
QUICConfig: &quic.Config{
Versions: []quic.Version{quic.Version1, quic.Version2},
InitialPacketSize: 1200,
Tracer: h3qlog.DefaultConnectionTracer,
},View on GitHub (pinned to 50e54ee279)
Solutions
- Use a standard network (tcp/tcp4/tcp6) for listeners that serve HTTP/3
- If you maintain the custom network type, call caddyhttp.RegisterNetworkHTTP3(original, h3net) with a UDP-based equivalent in an init() before serving
- Disable HTTP/3 (remove h3 from server protocols) for listeners on networks without QUIC support
Example fix
// before (custom network, no h3 mapping)
caddy.ListenPacket on "mysock" network with protocols ["h1","h2","h3"]
// after
func init() {
caddyhttp.RegisterNetworkHTTP3("mysock", "mysock_udp")
} Defensive patterns
Strategy: validation
Validate before calling
// before enabling h3 on a custom network:
registered := map[string]bool{"tcp": true, "tcp4": true, "tcp6": true} // + custom RegisterNetworkHTTP3 entries
if !registered[strings.ToLower(addr.Network)] && slices.Contains(s.Protocols, "h3") {
return fmt.Errorf("network %q cannot serve h3; register an HTTP/3 mapping or drop h3", addr.Network)
} Prevention
- Plugin authors: always pair custom network registration with RegisterNetworkHTTP3
- Keep h3 listeners on standard tcp networks
When it happens
Trigger: A server with HTTP/3 enabled whose listen address uses a network not registered for HTTP/3 (see RegisterNetworkHTTP3), e.g. a custom/Unix network string while protocols includes h3.
Common situations: Custom builds registering exotic network types (transparent sockets, Unix datagram) without also calling caddyhttp.RegisterNetworkHTTP3; enabling h3 on a server bound to a nonstandard network.
Related errors
- listening on %s: %v
- network '%s' cannot handle HTTP/1 or HTTP/2 connections
- making udp socket for HTTP/3 transport: %v
- network '%s' cannot handle HTTP/3 connections
- network type %s is reserved
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/73ad6c42d1a5c505.
Report an issue: GitHub.