apache/pulsar · error · IllegalArgumentException
invalid policy regex ${policy}
Error message
invalid policy regex ${policy} What it means
NamespaceIsolationDataImpl.validate compiles every entry of the namespaces regex list with java.util.regex.Pattern. If any non-blank regex has invalid syntax (PatternSyntaxException), validate throws IllegalArgumentException('invalid policy regex <policy>'), rejecting the whole namespace-isolation policy before it is stored.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/policies/data/NamespaceIsolationDataImpl.java:105
return new NamespaceIsolationDataImplBuilder();
}
public void validate() {
checkArgument(namespaces != null && !namespaces.isEmpty() && primary != null && !primary.isEmpty()
&& validateRegex(primary) && secondary != null && validateRegex(secondary)
&& autoFailoverPolicy != null);
autoFailoverPolicy.validate();
}
private boolean validateRegex(List<String> policies) {
if (policies != null && !policies.isEmpty()) {
policies.forEach((policy) -> {
try {
if (StringUtils.isNotBlank(policy)) {
Pattern.compile(policy);
}
} catch (PatternSyntaxException exception) {
throw new IllegalArgumentException("invalid policy regex " + policy);
}
});
}
return true;
}
public static class NamespaceIsolationDataImplBuilder implements NamespaceIsolationData.Builder {
private List<String> namespaces = new ArrayList<>();
private List<String> primary = new ArrayList<>();
private List<String> secondary = new ArrayList<>();
private AutoFailoverPolicyData autoFailoverPolicy;
private NamespaceIsolationPolicyUnloadScope unloadScope;
public NamespaceIsolationDataImplBuilder namespaces(List<String> namespaces) {
this.namespaces = namespaces;
return this;
}
View on GitHub (pinned to 820761864e)
Solutions
- Test the regex with Pattern.compile() (or any Java regex tester) before submitting; fix the syntax error reported by PatternSyntaxException.
- Remember these are Java regexes, not globs: use '.*' not '*' for wildcards and escape '.' as '\\.' where literal.
- Escape metacharacters ( [ ] ( ) * + ? \ ^ $ | ) or wrap literal parts with Pattern.quote().
- Remove or blank out broken list entries — blank entries are skipped, but syntactically invalid ones abort validation.
Example fix
// before
policy.setNamespaces(List.of("public/default/*")); // glob, invalid Java regex intent
policy.setNamespaces(List.of("public/default/[")); // syntax error
// after
policy.setNamespaces(List.of("public/default/.*")); // proper Java regex Defensive patterns
Strategy: validation
Validate before calling
static void validateNamespaceRegexes(java.util.Collection<String> namespaces) {
for (String p : namespaces) {
if (p != null && !p.isBlank()) {
try { java.util.regex.Pattern.compile(p); }
catch (java.util.regex.PatternSyntaxException e) {
throw new IllegalArgumentException("invalid policy regex " + p, e);
}
}
}
}
// call before setNamespaceIsolationPolicy Type guard
static boolean isValidRegex(String policy) {
if (policy == null || policy.isBlank()) return true;
try { java.util.regex.Pattern.compile(policy); return true; }
catch (java.util.regex.PatternSyntaxException e) { return false; }
} Try / catch
try {
admin.namespaces().setNamespaceIsolationPolicy(cluster, data);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("invalid policy regex")) {
// fix or Pattern.quote() the offending regex in data.getNamespaces()
}
throw e;
} Prevention
- Pre-compile every regex client-side before submitting the policy.
- Remember Java regex semantics: '.*' for wildcards, not glob '*'; escape '.' and other metacharacters.
- Use Pattern.quote() for literal namespace segments.
- Keep a test that compiles all shipped default policy regexes.
When it happens
Trigger: Submitting a NamespaceIsolationData (admin API: setNamespaceIsolationPolicy, or pulsar-admin namespaces set-namespace-isolation-policy) whose 'namespaces' list contains an invalid regex, e.g. 'public/[a-z(' (unbalanced bracket), '*', or a stray '+' or backslash.
Common situations: Hand-written namespace regexes with unescaped dots/brackets or trailing operators; assuming shell-style globs ('tenant/ns/*') work instead of regex ('tenant/ns/.*'); copy-paste losing characters.
Related errors
- Label name '%s' is invalid: must match the regex [a-zA-Z_][a
- Cannot derive a tenant/namespace from --regex pattern '${pat
- '${DEFAULT_CONFIG}' can't be modified.
- Invalid named entity: ${name}
- Batch Configs cannot be found
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/db9c409cb7371002.
Report an issue: GitHub.