caddyserver/caddy · critical
network type %s is already registered
Error message
network type %s is already registered
What it means
RegisterNetworkHTTP3 lets plugins map a custom listener network (registered via RegisterNetwork) to the network that its HTTP/3 (QUIC) listener should use. The mapping table is keyed by the original network name, lowercased; registering the same original network twice panics during init.
Source
Thrown at modules/caddyhttp/server.go:1506
var networkTypesHTTP3 = map[string]string{
"unixgram": "unixgram",
"udp": "udp",
"udp4": "udp4",
"udp6": "udp6",
"tcp": "udp",
"tcp4": "udp4",
"tcp6": "udp6",
"fdgram": "fdgram",
}
// RegisterNetworkHTTP3 registers a mapping from non-HTTP/3 network to HTTP/3
// network. This should be called during init() and will panic if the network
// type is standard, reserved, or already registered.
//
// EXPERIMENTAL: Subject to change.
func RegisterNetworkHTTP3(originalNetwork, h3Network string) {
if _, ok := networkTypesHTTP3[strings.ToLower(originalNetwork)]; ok {
panic("network type " + originalNetwork + " is already registered")
}
networkTypesHTTP3[originalNetwork] = h3Network
}
func getHTTP3Network(originalNetwork string) (string, error) {
h3Network, ok := networkTypesHTTP3[strings.ToLower(originalNetwork)]
if !ok {
return "", fmt.Errorf("network '%s' cannot handle HTTP/3 connections", originalNetwork)
}
return h3Network, nil
}
View on GitHub (pinned to 50e54ee279)
Solutions
- Ensure exactly one plugin owns the HTTP/3 mapping for a given network name
- Inspect linked plugins (caddy list-modules --packages) and de-duplicate imports/go.mod replaces
- Call RegisterNetworkHTTP3 only in the same init() that registers the network
Example fix
// before
// plugin A: caddyhttp.RegisterNetworkHTTP3("tunnel", "udp")
// plugin B: caddyhttp.RegisterNetworkHTTP3("tunnel", "udp") // panic
// after
// only plugin A registers it; plugin B omits the call Defensive patterns
Strategy: validation
Prevention
- One HTTP/3 registration per network name across the binary
- Call RegisterNetworkHTTP3 next to RegisterNetwork in the same init()
- De-duplicate linked plugins via go.mod replace
When it happens
Trigger: Two plugins both calling caddyhttp.RegisterNetworkHTTP3("myplugin:net", "udp") for the same original network, or one plugin registering it in two init paths.
Common situations: Fork/duplicate plugin linking (same as other duplicate-registration panics); a plugin bundle where two modules assume responsibility for the same custom network's HTTP/3 mapping.
Related errors
- network type %s is already registered
- network type %s is reserved
- module already registered: %s
- starting HTTP/3 QUIC listener: %v
- network '%s' cannot handle HTTP/3 connections
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/0ffeccce2bef96df.
Report an issue: GitHub.