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

  1. Use a standard network (tcp/tcp4/tcp6) for listeners that serve HTTP/3
  2. If you maintain the custom network type, call caddyhttp.RegisterNetworkHTTP3(original, h3net) with a UDP-based equivalent in an init() before serving
  3. 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

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


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/73ad6c42d1a5c505. Report an issue: GitHub.