apache/pulsar · error · IllegalArgumentException
Function Names differ
Error message
Function Names differ
What it means
Update-compatibility check in SourceConfigUtils.validateUpdate: the source's function name differs between the existing and new configuration (the tenant/namespace identity checks precede it), and renaming is not permitted via update; the changed function name is the faulty input.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java:389
return new ExtractedSourceDetails(sourceClassName, typeArg.asErasure().getTypeName());
}
@SneakyThrows
public static SourceConfig clone(SourceConfig sourceConfig) {
return ObjectMapperFactory.getMapper().reader().readValue(
ObjectMapperFactory.getMapper().writer().writeValueAsBytes(sourceConfig), SourceConfig.class);
}
public static SourceConfig validateUpdate(SourceConfig existingConfig, SourceConfig newConfig) {
SourceConfig mergedConfig = clone(existingConfig);
if (!existingConfig.getTenant().equals(newConfig.getTenant())) {
throw new IllegalArgumentException("Tenants differ");
}
if (!existingConfig.getNamespace().equals(newConfig.getNamespace())) {
throw new IllegalArgumentException("Namespaces differ");
}
if (!existingConfig.getName().equals(newConfig.getName())) {
throw new IllegalArgumentException("Function Names differ");
}
if (!StringUtils.isEmpty(newConfig.getClassName())) {
mergedConfig.setClassName(newConfig.getClassName());
}
if (!StringUtils.isEmpty(newConfig.getTopicName())) {
mergedConfig.setTopicName(newConfig.getTopicName());
}
if (!StringUtils.isEmpty(newConfig.getSerdeClassName())) {
mergedConfig.setSerdeClassName(newConfig.getSerdeClassName());
}
if (!StringUtils.isEmpty(newConfig.getSchemaType())) {
mergedConfig.setSchemaType(newConfig.getSchemaType());
}
if (newConfig.getConfigs() != null) {
mergedConfig.setConfigs(newConfig.getConfigs());
}
if (newConfig.getSecrets() != null) {
mergedConfig.setSecrets(newConfig.getSecrets());View on GitHub (pinned to 820761864e)
Solutions
- Keep the name identical when updating; delete+create to rename
Example fix
// before
{"tenant":"t1","namespace":"ns1","name":"src-renamed", ...}
// after
{"tenant":"t1","namespace":"ns1","name":"src1", ...} Defensive patterns
Strategy: validation
Validate before calling
if (!Objects.equals(existing.getName(), update.getName())) {
throw new IllegalArgumentException("name is immutable on update");
} Try / catch
try { SourceConfigUtils.validateUpdate(existing, update); } catch (IllegalArgumentException e) { if (e.getMessage().equals("Function Names differ")) { update.setName(existing.getName()); } else { throw e; } } Prevention
- Treat tenant/namespace/name as a primary key — never mutate in updates
- For renames, use delete + create
- Guard scripts that generate configs so the name field is read-only on update paths
When it happens
Trigger: validateUpdate receives a newConfig whose getName() differs from the existing config's name — e.g. an update payload for one source accidentally applied to another, or the name edited in a config template.
Common situations: Copy-pasting a source config, editing the name, then submitting it as an update to the original source; CI tooling that derives the name from a branch/feature flag; off-by-one in scripts iterating source configs.
Related errors
- Tenants differ
- Namespaces differ
- Function Names differ
- Input Topics cannot be altered
- isRegexPattern for input topic
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/97c132faaa4d1962.
Report an issue: GitHub.