{"record":{"id":"00a28f693a0f85f3","repo":"caddyserver/caddy","slug":"when-both-include-and-exclude-are-populated-each","errorCode":null,"errorMessage":"when both include and exclude are populated, each element must be a superspace or subspace of one in the other list; check '%s' in include","messagePattern":"when both include and exclude are populated, each element must be a superspace or subspace of one in the other list; check '(.+?)' in include","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"logging.go","lineNumber":519,"sourceCode":"\t// sets do not intersect, which is also a contradiction.\n\tif len(cl.Include) > 0 && len(cl.Exclude) > 0 {\n\t\t// prevent intersections\n\t\tfor _, allow := range cl.Include {\n\t\t\tif slices.Contains(cl.Exclude, allow) {\n\t\t\t\treturn fmt.Errorf(\"include and exclude must not intersect, but found %s in both lists\", allow)\n\t\t\t}\n\t\t}\n\n\t\t// ensure namespaces are nested\n\touter:\n\t\tfor _, allow := range cl.Include {\n\t\t\tfor _, deny := range cl.Exclude {\n\t\t\t\tif strings.HasPrefix(allow+\".\", deny+\".\") ||\n\t\t\t\t\tstrings.HasPrefix(deny+\".\", allow+\".\") {\n\t\t\t\t\tcontinue outer\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"when both include and exclude are populated, each element must be a superspace or subspace of one in the other list; check '%s' in include\", allow)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (cl *CustomLog) matchesModule(moduleID string) bool {\n\treturn cl.loggerAllowed(moduleID, true)\n}\n\n// loggerAllowed returns true if name is allowed to emit\n// to cl. isModule should be true if name is the name of\n// a module and you want to see if ANY of that module's\n// logs would be permitted.\nfunc (cl *CustomLog) loggerAllowed(name string, isModule bool) bool {\n\t// accept all loggers by default\n\tif len(cl.Include) == 0 && len(cl.Exclude) == 0 {\n\t\treturn true\n\t}","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/logging.go#L501-L537","documentation":"When both include and exclude are populated, every include entry must be a superspace or subspace of some exclude entry (dot-delimited namespace prefix relationship). An include entry that is unrelated to all exclude entries is neither a rule nor an exception, so validation fails naming the offending include element.","triggerScenarios":"include [\"http.handlers.reverse_proxy\"] with exclude [\"tls\"] — neither string is a dot-prefix of the other, so the pair is rejected. Nested pairs like include [\"http\"] / exclude [\"http.handlers\"] are fine because one contains the other.","commonSituations":"Trying to collect logs from unrelated subsystems while excluding an unrelated third subsystem in the same log sink; assuming include/exclude act as independent allow/deny lists (they don't when both are set — they must form rule+exception pairs).","solutions":["Restructure so each exclude entry is a parent or child namespace of an include entry (e.g. include \"http\", exclude \"http.handlers.file_server\").","Split unrelated include/exclude pairs into separate log blocks, each self-consistent.","Use include only (plus 'exclude' removed) when you simply want an allowlist."],"exampleFix":"// before (caddyfile)\nlog {\n    include http.handlers.reverse_proxy\n    exclude tls.issuance\n}\n\n// after — split into consistent sinks\nlog rp {\n    include http.handlers.reverse_proxy\n    output file /var/log/caddy/rp.log\n}\nlog tls {\n    include tls\n    exclude tls.issuance.acme\n    output file /var/log/caddy/tls.log\n}","handlingStrategy":"validation","validationCode":"// enforce the nesting rule client-side before load\nfunc nested(include, exclude []string) error {\nouter:\n    for _, inc := range include {\n        for _, exc := range exclude {\n            if strings.HasPrefix(inc+\".\", exc+\".\") || strings.HasPrefix(exc+\".\", inc+\".\") {\n                continue outer\n            }\n        }\n        return fmt.Errorf(\"include %s is unrelated to every exclude entry\", inc)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := caddy.Validate(cfg); err != nil {\n    if strings.Contains(err.Error(), \"superspace or subspace\") {\n        // restructure into rule+exception pairs or split sinks\n    }\n    return err\n}","preventionTips":["Model include as rules and exclude as exceptions — never as two independent filters.","Split unrelated namespaces into separate log blocks.","Prefer broad include (\"http\") with narrow exclude (\"http.handlers.file_server\") patterns."],"tags":["logging","validation","namespaces"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}