apache/pulsar · error · IllegalArgumentException

DiscoverTriggerer class cannot be updated for batchsources

Error message

DiscoverTriggerer class cannot be updated for batchsources

What it means

During batch source updates, validateBatchSourceConfigUpdate enforces that the discovery triggerer class stays the same, because swapping it would change how the running source discovers batches mid-lifecycle. Any change is rejected with this message.

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java:512

    }

    public static String computeBatchSourceInstanceSubscriptionName(String tenant, String namespace,
                                                                    String sourceName) {
        return "BatchSourceExecutor-" + tenant + "/" + namespace + "/" + sourceName;
    }

    public static TopicName computeBatchSourceIntermediateTopicName(String tenant, String namespace,
                                                                    String sourceName) {
        return TopicName.get(TopicDomain.persistent.name(), tenant, namespace, sourceName + "-intermediate");
    }

    public static boolean isBatchSource(SourceConfig sourceConfig) {
        return sourceConfig.getBatchSourceConfig() != null;
    }

    public static void validateBatchSourceConfigUpdate(BatchSourceConfig existingConfig, BatchSourceConfig newConfig) {
        if (!existingConfig.getDiscoveryTriggererClassName().equals(newConfig.getDiscoveryTriggererClassName())) {
            throw new IllegalArgumentException("DiscoverTriggerer class cannot be updated for batchsources");
        }
    }

    public static void validateSourceConfig(SourceConfig sourceConfig, ValidatableFunctionPackage sourceFunction) {
        try {
            ConnectorDefinition defn = sourceFunction.getFunctionMetaData(ConnectorDefinition.class);
            if (defn != null && defn.getSourceConfigClass() != null) {
                Class<?> configClass =
                        Class.forName(defn.getSourceConfigClass(), true, sourceFunction.getClassLoader());
                validateSourceConfig(sourceConfig, configClass);
            }
        } catch (ClassNotFoundException e) {
            throw new IllegalArgumentException("Could not find source config class");
        }

    }

    public static void validateSourceConfig(SourceConfig sourceConfig, Class<?> configClass) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Resubmit the update keeping discoveryTriggererClassName identical to the existing value
  2. If a different triggerer is required, delete and recreate the batch source with the new config
  3. Adjust tooling so only discoveryTriggererConfig (not the class) is changed on updates

Example fix

// before
{"batchSourceConfig":{"discoveryTriggererClassName":"com.example.NewTriggerer", ...}}
// after
{"batchSourceConfig":{"discoveryTriggererClassName":"com.example.OldTriggerer", ...}} // same class as existing
Defensive patterns

Strategy: validation

Validate before calling

if (existing.getBatchSourceConfig() != null && update.getBatchSourceConfig() != null
    && !existing.getBatchSourceConfig().getDiscoveryTriggererClassName()
        .equals(update.getBatchSourceConfig().getDiscoveryTriggererClassName())) {
    throw new IllegalArgumentException("discoveryTriggererClassName is immutable on update");
}

Try / catch

try { SourceConfigUtils.validateUpdate(existing, update); } catch (IllegalArgumentException e) { if (e.getMessage().contains("DiscoverTriggerer class cannot be updated")) { update.getBatchSourceConfig().setDiscoveryTriggererClassName(existing.getBatchSourceConfig().getDiscoveryTriggererClassName()); } else { throw e; } }

Prevention

When it happens

Trigger: validateUpdate on a batch source where existingConfig.getBatchSourceConfig().getDiscoveryTriggererClassName() differs from the new config's value.

Common situations: Operator switches to a different/improved triggerer implementation via update instead of recreation; template upgrade bumps the triggerer class; drift between environments leads to mismatched triggerer classes in update payloads.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/1f2b02fa35440600. Report an issue: GitHub.