{"record":{"id":"c3ff18e1700fbe58","repo":"caddyserver/caddy","slug":"module-s-t-is-not-an-ip-range-source","errorCode":null,"errorMessage":"module %s (%T) is not an IP range source","messagePattern":"module (.+?) \\(%T\\) is not an IP range source","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"caddyconfig/httpcaddyfile/serveroptions.go","lineNumber":279,"sourceCode":"\t\t\t}\n\t\t\tboolVal := true\n\t\t\tif d.Val() == \"insecure_off\" {\n\t\t\t\tboolVal = false\n\t\t\t}\n\t\t\tserverOpts.StrictSNIHost = &boolVal\n\n\t\tcase \"trusted_proxies\":\n\t\t\tif !d.NextArg() {\n\t\t\t\treturn nil, d.Err(\"trusted_proxies expects an IP range source module name as its first argument\")\n\t\t\t}\n\t\t\tmodID := \"http.ip_sources.\" + d.Val()\n\t\t\tunm, err := caddyfile.UnmarshalModule(d, modID)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tsource, ok := unm.(caddyhttp.IPRangeSource)\n\t\t\tif !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"module %s (%T) is not an IP range source\", modID, unm)\n\t\t\t}\n\t\t\tjsonSource := caddyconfig.JSONModuleObject(\n\t\t\t\tsource,\n\t\t\t\t\"source\",\n\t\t\t\tsource.(caddy.Module).CaddyModule().ID.Name(),\n\t\t\t\tnil,\n\t\t\t)\n\t\t\tserverOpts.TrustedProxiesRaw = jsonSource\n\n\t\tcase \"trusted_proxies_strict\":\n\t\t\tif d.NextArg() {\n\t\t\t\treturn nil, d.ArgErr()\n\t\t\t}\n\t\t\tserverOpts.TrustedProxiesStrict = 1\n\n\t\tcase \"trusted_proxies_unix\":\n\t\t\tif d.NextArg() {\n\t\t\t\treturn nil, d.ArgErr()","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/caddyconfig/httpcaddyfile/serveroptions.go#L261-L297","documentation":"The 'trusted_proxies <module> ...' server option unmarshals a module from 'http.ip_sources.' (e.g. static, cloudflare) and asserts it implements caddyhttp.IPRangeSource. Note that a misspelled or missing module name fails earlier inside caddyfile.UnmarshalModule; this specific error fires only when the module unmarshals fine but does not implement the IP range source interface — i.e. a broken or incompatible plugin in that namespace.","triggerScenarios":"A plugin registering a module under http.ip_sources that does not implement GetIPRanges; a custom IP source module compiled against an older Caddy where the interface differed.","commonSituations":"Developing a custom trusted-proxy IP source and forgetting the interface; version skew between a third-party ip_sources plugin and Caddy core.","solutions":["Check which modules are registered: 'caddy list-modules | grep http.ip_sources' and use a documented one (static, cloudflare).","Rebuild the plugin against your Caddy version.","If developing the module, implement caddyhttp.IPRangeSource (GetIPRanges) and add a compile-time guard."],"exampleFix":"# use a valid, documented IP range source\nservers {\n  trusted_proxies static 10.0.0.0/8 172.16.0.0/12\n}","handlingStrategy":"validation","validationCode":"caddy list-modules | grep '^http.ip_sources.'  # e.g. static, cloudflare","typeGuard":"var _ caddyhttp.IPRangeSource = (*StaticRanges)(nil)","tryCatchPattern":null,"preventionTips":["Use only documented IP sources (static, cloudflare) or verify your custom one implements IPRangeSource.","Adapt configs in CI to catch bad module references early."],"tags":["caddyfile","trusted-proxies","ip-source","plugin"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}