{"id":"c4b57e83a74656f9","repo":"apache/kafka","slug":"jmx-filter-for-configuration-metricsconfigprefix","errorCode":null,"errorMessage":"JMX filter for configuration{metricsConfigPrefix}.(include/exclude) is not a valid regular expression","messagePattern":"JMX filter for configuration(.+?)\\.\\(include/exclude\\) is not a valid regular expression","errorType":"validation","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/metrics/JmxReporter.java","lineNumber":316,"sourceCode":"        String include = (String) configs.get(INCLUDE_CONFIG);\n        String exclude = (String) configs.get(EXCLUDE_CONFIG);\n\n        if (include == null) {\n            include = DEFAULT_INCLUDE;\n        }\n\n        if (exclude == null) {\n            exclude = DEFAULT_EXCLUDE;\n        }\n\n        try {\n            Pattern includePattern = Pattern.compile(include);\n            Pattern excludePattern = Pattern.compile(exclude);\n\n            return s -> includePattern.matcher(s).matches()\n                        && !excludePattern.matcher(s).matches();\n        } catch (PatternSyntaxException e) {\n            throw new ConfigException(\"JMX filter for configuration\" + METRICS_CONFIG_PREFIX\n                                      + \".(include/exclude) is not a valid regular expression\");\n        }\n    }\n\n    @Override\n    public void contextChange(MetricsContext metricsContext) {\n        String namespace = metricsContext.contextLabels().get(MetricsContext.NAMESPACE);\n        Objects.requireNonNull(namespace);\n        synchronized (LOCK) {\n            if (!mbeans.isEmpty()) {\n                throw new IllegalStateException(\"JMX MetricsContext can only be updated before JMX metrics are created\");\n            }\n\n            // prevent prefix from getting reset back to empty for backwards compatibility\n            // with the deprecated JmxReporter(String prefix) constructor, in case contextChange gets called\n            // via one of the Metrics() constructor with a default empty MetricsContext()\n            if (namespace.isEmpty()) {\n                return;","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/metrics/JmxReporter.java#L298-L334","documentation":"Thrown by JmxReporter.compilePredicate when either the metrics include or exclude filter string fails to compile as a java.util.regex.Pattern. Kafka exposes metrics through JMX optionally filtered by two regex configs (prefixed with metrics.<prefix>.include / .exclude); both must be valid regular expressions. The raw PatternSyntaxException is wrapped and rethrown as a ConfigException so the failure surfaces clearly at client/broker startup.","triggerScenarios":"Client or broker config sets a property under the METRICS_CONFIG_PREFIX whose key ends in .include or .exclude to a malformed regex (unbalanced brackets, dangling metacharacter, invalid quantifier). Pattern.compile throws PatternSyntaxException inside compilePredicate; the catch block at JmxReporter.java:315-318 rethrows ConfigException.","commonSituations":"Migrating a metrics filter between regex dialects (e.g. copying a Python re pattern into the Kafka config). Typing a glob like \"kafka.*\" with characters that are regex metacharacters. Inadvertently setting include/exclude via environment variable substitution that yields an empty or partial token. Mixing YAML/properties escaping that strips a closing bracket.","solutions":["Locate the metrics.<prefix>.include and metrics.<prefix>.exclude config keys in the affected client/broker properties.","Validate each value with a quick java.util.regex.Pattern.compile check in a REPL/JUnit before redeploying.","Correct the regex (escape metacharacters with backslash, balance character classes, fix quantifiers) or replace it with a simpler literal-prefix filter.","Restart the client/broker and confirm metrics publish to JMX without the ConfigException."],"exampleFix":"// before: metrics.include=record(.+   // unterminated group, illegal regex\n// after:  metrics.include=record.+","handlingStrategy":"validation","validationCode":"// Validate include/exclude regex BEFORE building configs consumed by JmxReporter.\nString include = (String) configs.getOrDefault(JmxReporter.METRICS_CONFIG_PREFIX + \".include\", JmxReporter.DEFAULT_INCLUDE);\nString exclude = (String) configs.getOrDefault(JmxReporter.METRICS_CONFIG_PREFIX + \".exclude\", JmxReporter.DEFAULT_EXCLUDE);\nfor (String re : new String[]{include, exclude}) {\n    try { Pattern.compile(re); }\n    catch (PatternSyntaxException e) {\n        throw new IllegalArgumentException(\"Invalid JMX metrics regex: \" + re, e);\n    }\n}","typeGuard":"// Type/narrowing helper: confirm a candidate value is a compilable regex.\nboolean isValidRegex(String s) {\n    if (s == null) return false;\n    try { Pattern.compile(s); return true; } catch (PatternSyntaxException e) { return false; }\n}","tryCatchPattern":"try {\n    Predicate<String> p = JmxReporter.compilePredicate(configs);\n} catch (ConfigException e) {\n    // fall back to defaults or fail config loading with a clear user message\n    configs.remove(JmxReporter.METRICS_CONFIG_PREFIX + \".include\");\n    configs.remove(JmxReporter.METRICS_CONFIG_PREFIX + \".exclude\");\n}","preventionTips":["Treat metrics.include/exclude as user-supplied config; never trust raw input.","Test regex with Pattern.compile in your config validation layer before passing to Kafka.","Use anchored, simple regexes; avoid backtracking patterns that compile but perform poorly.","Provide a config UI that surfaces PatternSyntaxException at setting time."],"tags":["config","regex","jmx","metrics","startup"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}