{"record":{"id":"2fa14a54f8ab478e","repo":"caddyserver/caddy","slug":"module-s-t-is-not-a-listener-wrapper","errorCode":null,"errorMessage":"module %s (%T) is not a listener wrapper","messagePattern":"module (.+?) \\(%T\\) is not a listener wrapper","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"caddyconfig/httpcaddyfile/serveroptions.go","lineNumber":97,"sourceCode":"\t\tcase \"name\":\n\t\t\tif serverOpts.ListenerAddress == \"\" {\n\t\t\t\treturn nil, d.Errf(\"cannot set a name for a server without a listener address\")\n\t\t\t}\n\t\t\tif !d.NextArg() {\n\t\t\t\treturn nil, d.ArgErr()\n\t\t\t}\n\t\t\tserverOpts.Name = d.Val()\n\n\t\tcase \"listener_wrappers\":\n\t\t\tfor nesting := d.Nesting(); d.NextBlock(nesting); {\n\t\t\t\tmodID := \"caddy.listeners.\" + d.Val()\n\t\t\t\tunm, err := caddyfile.UnmarshalModule(d, modID)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tlistenerWrapper, ok := unm.(caddy.ListenerWrapper)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, fmt.Errorf(\"module %s (%T) is not a listener wrapper\", modID, unm)\n\t\t\t\t}\n\t\t\t\tjsonListenerWrapper := caddyconfig.JSONModuleObject(\n\t\t\t\t\tlistenerWrapper,\n\t\t\t\t\t\"wrapper\",\n\t\t\t\t\tlistenerWrapper.(caddy.Module).CaddyModule().ID.Name(),\n\t\t\t\t\tnil,\n\t\t\t\t)\n\t\t\t\tserverOpts.ListenerWrappersRaw = append(serverOpts.ListenerWrappersRaw, jsonListenerWrapper)\n\t\t\t}\n\n\t\tcase \"packet_conn_wrappers\":\n\t\t\tfor nesting := d.Nesting(); d.NextBlock(nesting); {\n\t\t\t\tmodID := \"caddy.packetconns.\" + d.Val()\n\t\t\t\tunm, err := caddyfile.UnmarshalModule(d, modID)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tpacketConnWrapper, ok := unm.(caddy.PacketConnWrapper)","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/caddyconfig/httpcaddyfile/serveroptions.go#L79-L115","documentation":"In a server options block ('servers { listener_wrappers { ... } }'), the named module under 'caddy.listeners.' is unmarshaled via caddyfile.UnmarshalModule and then asserted to implement caddy.ListenerWrapper. If the assertion fails, the module cannot wrap the listener and adapt aborts. Typical cause: a plugin built for an incompatible Caddy version or a module registered in that namespace without implementing the wrapper interface.","triggerScenarios":"A listener-wrapper plugin registered under caddy.listeners that lacks the WrapListener method; a plugin compiled against an older Caddy where the ListenerWrapper interface differed; version skew between core and plugin after an upgrade.","commonSituations":"Configuring 'listener_wrappers { proxy_protocol }' with a plugin not rebuilt for the current core; upgrading Caddy core without rebuilding listener plugins; copy-pasting server options from a different distribution's docs.","solutions":["Confirm the module exists and its namespace: 'caddy list-modules | grep caddy.listeners'.","Rebuild with xcaddy including the wrapper plugin at a version matching core.","If the plugin is yours, implement caddy.ListenerWrapper (WrapListener) and add an interface guard."],"exampleFix":"# before: plugin missing from this build\n{\n  servers {\n    listener_wrappers {\n      proxy_protocol\n    }\n  }\n}\n\n# after: build with the plugin, then the same config works\n# xcaddy build --with github.com/mastercactapult/caddy-proxyprotocol","handlingStrategy":"validation","validationCode":"caddy list-modules | grep '^caddy.listeners.'  # confirm the wrapper exists in this build","typeGuard":"var _ caddy.ListenerWrapper = (*MyWrapper)(nil)","tryCatchPattern":null,"preventionTips":["Check module availability with caddy list-modules before writing server options for custom builds.","Keep xcaddy build recipes in version control so listener wrapper plugins are never forgotten."],"tags":["caddyfile","server-options","listener-wrapper","plugin"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}