apache/pulsar · error · IllegalArgumentException
isRegexPattern for input topic
Error message
isRegexPattern for input topic
What it means
For each input topic already registered on a function, the isRegexPattern flag is immutable: an update cannot convert a plain topic subscription into a regex pattern subscription or vice versa. The message is followed by the offending topic name.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java:1048
.build());
});
}
if (newConfig.getCustomSchemaInputs() != null) {
newConfig.getCustomSchemaInputs().forEach((topicName, schemaClassname) -> {
newConfig.getInputSpecs().put(topicName,
ConsumerConfig.builder()
.schemaType(schemaClassname)
.isRegexPattern(false)
.build());
});
}
if (!newConfig.getInputSpecs().isEmpty()) {
newConfig.getInputSpecs().forEach((topicName, consumerConfig) -> {
if (!existingConfig.getInputSpecs().containsKey(topicName)) {
throw new IllegalArgumentException("Input Topics cannot be altered");
}
if (consumerConfig.isRegexPattern() != existingConfig.getInputSpecs().get(topicName).isRegexPattern()) {
throw new IllegalArgumentException(
"isRegexPattern for input topic " + topicName + " cannot be altered");
}
mergedConfig.getInputSpecs().put(topicName, consumerConfig);
});
}
if (!StringUtils.isEmpty(newConfig.getOutputSerdeClassName()) && !newConfig.getOutputSerdeClassName()
.equals(existingConfig.getOutputSerdeClassName())) {
throw new IllegalArgumentException("Output Serde mismatch");
}
if (!StringUtils.isEmpty(newConfig.getOutputSchemaType()) && !newConfig.getOutputSchemaType()
.equals(existingConfig.getOutputSchemaType())) {
throw new IllegalArgumentException("Output Schema mismatch");
}
if (!StringUtils.isEmpty(newConfig.getLogTopic())) {
mergedConfig.setLogTopic(newConfig.getLogTopic());
}
if (newConfig.getProcessingGuarantees() != null && !newConfig.getProcessingGuarantees()
.equals(existingConfig.getProcessingGuarantees())) {View on GitHub (pinned to 820761864e)
Solutions
- Keep isRegexPattern unchanged for every existing input topic in the update payload.
- If the pattern behavior must change, delete and recreate the function with the desired isRegexPattern values.
- Check ConsumerConfig construction for defaults that flip isRegexPattern (e.g. builder defaults or YAML `regexPattern:` key).
Example fix
// before
ConsumerConfig cc = ConsumerConfig.builder().topicName("persistent://public/default/t1")
.isRegexPattern(true).build(); // existing has false
// after
ConsumerConfig cc = ConsumerConfig.builder().topicName("persistent://public/default/t1")
.isRegexPattern(existingConfig.getInputSpecs().get("persistent://public/default/t1").isRegexPattern()).build(); Defensive patterns
Strategy: validation
Validate before calling
newConfig.getInputSpecs().forEach((topic, cc) -> {
ConsumerConfig ex = existingConfig.getInputSpecs().get(topic);
if (ex != null && ex.isRegexPattern() != cc.isRegexPattern()) {
throw new IllegalArgumentException("isRegexPattern mismatch for topic " + topic);
}
}); Type guard
boolean regexFlagsUnchanged(FunctionConfig existing, FunctionConfig updated) {
return updated.getInputSpecs().entrySet().stream().allMatch(e -> {
ConsumerConfig ex = existing.getInputSpecs().get(e.getKey());
return ex == null || ex.isRegexPattern() == e.getValue().isRegexPattern();
});
} Try / catch
try {
merged = FunctionConfigUtils.validateUpdate(existing, updated);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("isRegexPattern for input topic")) {
String topic = e.getMessage().replace("isRegexPattern for input topic ", "").replace(" cannot be altered", "");
throw new IllegalStateException("Recreate the function to change isRegexPattern for " + topic, e);
} else { throw e; }
} Prevention
- Copy isRegexPattern from the existing ConsumerConfig when building update payloads.
- Avoid tooling defaults that force isRegexPattern=true.
- Diff ConsumerConfig flags between create and update configs.
When it happens
Trigger: Updating a function where, for a topic present in both existing and new inputSpecs, consumerConfig.isRegexPattern() differs from the existing ConsumerConfig's isRegexPattern() for that topic.
Common situations: Switching a topic from exact subscription to pattern (or back) to simplify config; tooling that generates regex:true for all topics by default; merging configs from environments where the flag was set differently.
Related errors
- Tenants differ
- Namespaces differ
- Function Names differ
- Input Topics cannot be altered
- Output Serde mismatch
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/98ca0fec26366b7a.
Report an issue: GitHub.