apache/pulsar · error · IllegalArgumentException
Subscription Name cannot be altered
Error message
Subscription Name cannot be altered
What it means
Thrown by SinkConfigUtils.validateUpdate when sourceSubscriptionName is set in the new config and differs from the existing one. The Pulsar subscription a sink consumes from is fixed after creation, so changing it is rejected to avoid silently switching the consumption source.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java:626
public static SinkConfig validateUpdate(SinkConfig existingConfig, SinkConfig newConfig) {
SinkConfig 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("Sink Names differ");
}
if (!StringUtils.isEmpty(newConfig.getClassName())) {
mergedConfig.setClassName(newConfig.getClassName());
}
if (!StringUtils.isEmpty(newConfig.getSourceSubscriptionName()) && !newConfig.getSourceSubscriptionName()
.equals(existingConfig.getSourceSubscriptionName())) {
throw new IllegalArgumentException("Subscription Name cannot be altered");
}
if (newConfig.getInputSpecs() == null) {
newConfig.setInputSpecs(new HashMap<>());
}
if (mergedConfig.getInputSpecs() == null) {
mergedConfig.setInputSpecs(new HashMap<>());
}
if (!StringUtils.isEmpty(newConfig.getLogTopic())) {
mergedConfig.setLogTopic(newConfig.getLogTopic());
}
if (newConfig.getInputs() != null) {
newConfig.getInputs().forEach((topicName -> {
newConfig.getInputSpecs().putIfAbsent(topicName,
ConsumerConfig.builder().isRegexPattern(false).build());
}));View on GitHub (pinned to 820761864e)
Solutions
- Set sourceSubscriptionName in the update config to the same value as the existing sink (or leave it empty to keep it)
- If a different subscription is required, delete and re-create the sink with the new subscription name
- Check the current value via 'pulsar-admin sinks get' before updating
Example fix
// before
sinkConfig.setSourceSubscriptionName("new-sub");
admin.sinks().updateSink(tenant, namespace, sinkConfig, null);
// after
sinkConfig.setSourceSubscriptionName("original-sub"); // must match existing
admin.sinks().updateSink(tenant, namespace, sinkConfig, null); Defensive patterns
Strategy: validation
Validate before calling
if (newCfg.getSourceSubscriptionName() != null
&& !newCfg.getSourceSubscriptionName().isEmpty()
&& !newCfg.getSourceSubscriptionName().equals(existing.getSourceSubscriptionName())) {
throw new IllegalArgumentException("sourceSubscriptionName is immutable");
} Try / catch
try {
admin.sinks().updateSink(tenant, namespace, cfg, null);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Subscription Name cannot be altered")) { /* revert to existing subscription */ }
else throw e;
} Prevention
- Leave sourceSubscriptionName unset in update payloads
- Keep one canonical source-of-truth config per sink to avoid drifted subscription names
- Recreate the sink if the subscription must change
When it happens
Trigger: Updating a sink while passing a non-empty getSourceSubscriptionName() that does not equal the existing config's subscription name (including changing it from a configured value to a different one).
Common situations: Teams rename subscriptions in shared config; a sink created with subscription 'sub-a' is updated with 'sub-b'; user tries to point an existing sink at a different topic subscription instead of recreating it.
Related errors
- Sink Names differ
- Input Topics cannot be altered
- isRegexPattern for input topic cannot be altered
- Processing Guarantees cannot be altered
- Retain Ordering cannot be altered
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/c2381b2d490f87a7.
Report an issue: GitHub.