caddyserver/caddy · error
loading packet conn wrapper modules: %v
Error message
loading packet conn wrapper modules: %v
What it means
ctx.LoadModule instantiates servers.<name>.packet_conn_wrappers (modules implementing caddy.PacketConnWrapper, which wrap UDP/QUIC sockets before the QUIC handshake). Any unregistered module ID or failing Provision aborts app provisioning. There is no QUIC placeholder wrapper, unlike the TLS chain.
Source
Thrown at modules/caddyhttp/app.go:357
}
hasTLSPlaceholder = true
}
srv.listenerWrappers = append(srv.listenerWrappers, val.(caddy.ListenerWrapper))
}
// if any wrappers were configured but the TLS placeholder wrapper is
// absent, prepend it so all defined wrappers come after the TLS
// handshake; this simplifies logic when starting the server, since we
// can simply assume the TLS placeholder will always be there
if !hasTLSPlaceholder && len(srv.listenerWrappers) > 0 {
srv.listenerWrappers = append([]caddy.ListenerWrapper{new(tlsPlaceholderWrapper)}, srv.listenerWrappers...)
}
}
// set up each packet conn modifier
if srv.PacketConnWrappersRaw != nil {
vals, err := ctx.LoadModule(srv, "PacketConnWrappersRaw")
if err != nil {
return fmt.Errorf("loading packet conn wrapper modules: %v", err)
}
// if any wrappers were configured, they come before the QUIC handshake;
// unlike TLS above, there is no QUIC placeholder
for _, val := range vals.([]any) {
srv.packetConnWrappers = append(srv.packetConnWrappers, val.(caddy.PacketConnWrapper))
}
}
// pre-compile the primary handler chain, and be sure to wrap it in our
// route handler so that important security checks are done, etc.
primaryRoute := emptyHandler
if srv.Routes != nil {
err := srv.Routes.ProvisionHandlers(ctx, app.Metrics)
if err != nil {
return fmt.Errorf("server %s: setting up route handlers: %v", srvName, err)
}
primaryRoute = srv.Routes.Compile(emptyHandler)
}View on GitHub (pinned to 50e54ee279)
Solutions
- Check the wrapped error for the module name or option at fault
- Build with the required plugin (xcaddy build --with ...) or drop the entry
- Confirm the module actually implements PacketConnWrapper, not ListenerWrapper
Defensive patterns
Strategy: validation
Validate before calling
// ensure the module is compiled in before load
out, _ := exec.Command("caddy", "list-modules").Output()
for _, w := range srvCfg.PacketConnWrappersRaw {
id := gjson.GetBytes(w, "wrapper").String()
if !strings.Contains(string(out), id) {
return fmt.Errorf("packet conn wrapper %q missing from build", id)
}
} Prevention
- Document packet_conn_wrappers plugin requirements in the repo README
- Validate config in the target container image, not on a dev machine with different plugins
When it happens
Trigger: A packet_conn_wrappers entry referencing a module not compiled into the binary, a typo'd module ID, or a wrapper whose own provisioning fails on its options.
Common situations: Using QUIC/HTTP/3 with a custom packet-filtering plugin that is missing from the build; copying configs between builds with different plugins.
Related errors
- loading listener wrapper modules: %v
- --config is required
- encoding new config: %v
- loading storage module: %v
- creating storage value: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/3a09e979e8255539.
Report an issue: GitHub.