{"record":{"id":"b1b71d6214763a38","repo":"vectordotdev/vector","slug":"the-pattern-is-supposed-to-always-be-correct","errorCode":null,"errorMessage":"the pattern is supposed to always be correct","messagePattern":"the pattern is supposed to always be correct","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/sources/kubernetes_logs/k8s_paths_provider.rs","lineNumber":190,"sourceCode":"            // and cache the results into a Vec.\n            let excluded_containers = extract_excluded_containers_for_pod(pod);\n            let exclusion_patterns: Vec<_> =\n                build_container_exclusion_patterns(dir, excluded_containers).collect();\n\n            // Return paths filtered with container exclusion.\n            filter_paths(path_iter, exclusion_patterns, false)\n        })\n}\n\nfn real_glob(pattern: &str) -> impl Iterator<Item = PathBuf> + use<> {\n    glob::glob_with(\n        pattern,\n        glob::MatchOptions {\n            require_literal_separator: true,\n            ..Default::default()\n        },\n    )\n    .expect(\"the pattern is supposed to always be correct\")\n    .flat_map(|paths| paths.into_iter())\n}\n\nfn filter_paths<'a>(\n    iter: impl Iterator<Item = PathBuf> + 'a,\n    patterns: impl AsRef<[glob::Pattern]> + 'a,\n    include: bool,\n) -> impl Iterator<Item = PathBuf> + 'a {\n    iter.filter(move |path| {\n        let m = patterns.as_ref().iter().any(|pattern| {\n            pattern.matches_path_with(\n                path,\n                glob::MatchOptions {\n                    require_literal_separator: true,\n                    ..Default::default()\n                },\n            )\n        });","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/vectordotdev/vector/blob/3708c39b12a93212ed8b8d7510b4cc7769cb5864/src/sources/kubernetes_logs/k8s_paths_provider.rs#L172-L208","documentation":"Panic from `glob::glob_with(...)` returning a `PatternError`. The pattern is built as `[dir, \"*/*.log*\"].join(\"/\")`, and glob treats `[`, `]`, `{`, `}`, `*`, `?` as syntax. If the directory portion contains unbalanced or reserved glob metacharacters, the pattern fails to parse and `expect(\"the pattern is supposed to always be correct\")` aborts the kubernetes_logs path provider.","triggerScenarios":"A pod logs directory containing glob metacharacters — e.g. an annotation or hostPath like `/data/pods[1]/logs` or `/var/log/{app}/pod` — which makes the joined pattern `<dir>/*/*.log*` unparseable by the glob crate.","commonSituations":"Custom log-directory annotations using shell-glob-style names (`{...}`, `[...]`, stray `*`). Stock kubelet directories never contain these characters, so this fires only with operator-supplied paths.","solutions":["Remove glob metacharacters (`* ? [ ] { }`) from the custom pod logs directory path or annotation","If embedding: escape the directory with `glob::Pattern::escape(dir)` before joining the wildcard suffix","Upgrade Vector / patch the provider to handle PatternError as a skipped pod instead of a panic"],"exampleFix":"// before\nlet path_iter = glob_impl(&[dir, \"*/*.log*\"].join(\"/\"));\n// after\nlet pattern = [glob::Pattern::escape(dir), \"*/*.log*\".to_owned()].join(\"/\");\nlet path_iter = glob_impl(&pattern);","handlingStrategy":"validation","validationCode":"// Rust: pre-flight the pattern before handing it to glob\nlet pattern = [dir, \"*/*.log*\"].join(\"/\");\nif glob::Pattern::new(&pattern).is_err() {\n    warn!(message = \"pod logs dir contains glob metacharacters\", dir);\n}","typeGuard":"fn glob_safe(dir: &str) -> bool {\n    glob::Pattern::new(&[dir, \"*/*.log*\"].join(\"/\")).is_ok()\n}","tryCatchPattern":null,"preventionTips":["Escape directory segments with glob::Pattern::escape before appending wildcards","Avoid `* ? [ ] { }` in any operator-supplied path that feeds a glob","Unit-test path providers with adversarial directory names"],"tags":["glob","kubernetes-logs","pattern","path","panic"],"backgroundTag":"glob-pattern-parse-error","analyzedSha":"3708c39b12a93212ed8b8d7510b4cc7769cb5864","analyzedAt":"2026-08-20T07:02:18.786Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}