apache/pulsar · error · IllegalArgumentException

Input topic %s is invalid

Error message

Input topic %s is invalid

What it means

Pulsar Functions validate every configured input topic name before a function is created or updated. This error is thrown by FunctionConfigUtils.doCommonChecks when any topic collected from the function's input list fails TopicName.isValid(), meaning it is not a syntactically valid Pulsar topic name (e.g. missing namespace/tenant components or illegal characters).

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java:812

            throw new IllegalArgumentException("Function namespace cannot be null");
        }
        if (isEmpty(functionConfig.getName())) {
            throw new IllegalArgumentException("Function name cannot be null");
        }
        // go doesn't need className. Java className is done in doJavaChecks.
        if (functionConfig.getRuntime() == FunctionConfig.Runtime.PYTHON) {
            if (isEmpty(functionConfig.getClassName())) {
                throw new IllegalArgumentException("Function classname cannot be null");
            }
        }

        Collection<String> allInputTopics = collectAllInputTopics(functionConfig);
        if (allInputTopics.isEmpty()) {
            throw new IllegalArgumentException("No input topic(s) specified for the function");
        }
        for (String topic : allInputTopics) {
            if (!TopicName.isValid(topic)) {
                throw new IllegalArgumentException(String.format("Input topic %s is invalid", topic));
            }
        }

        if (!isEmpty(functionConfig.getOutput())) {
            if (!TopicName.isValid(functionConfig.getOutput())) {
                throw new IllegalArgumentException(
                        String.format("Output topic %s is invalid", functionConfig.getOutput()));
            }
        }

        if (!isEmpty(functionConfig.getLogTopic())) {
            if (!TopicName.isValid(functionConfig.getLogTopic())) {
                throw new IllegalArgumentException(
                        String.format("LogTopic topic %s is invalid", functionConfig.getLogTopic()));
            }
        }

        if (!isEmpty(functionConfig.getDeadLetterTopic())) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Fix the input topic to a fully qualified Pulsar topic name: [persistent|non-persistent://]<tenant>/<namespace>/<topic>, e.g. persistent://public/default/in-topic
  2. If using a short name, rely on the configured default tenant/namespace instead of passing an invalid bare name
  3. Trim whitespace and remove illegal characters (spaces, empty segments) from the topic string
  4. Verify with org.apache.pulsar.common.naming.TopicName.isValid(topic) in a unit test before deploying

Example fix

// before
config.setInput(Collections.singletonMap("my-input-topic", null));
// after
config.setInput(Collections.singletonMap("persistent://public/default/my-input-topic", null));
Defensive patterns

Strategy: validation

Validate before calling

import org.apache.pulsar.common.naming.TopicName;
for (String topic : config.getInput().keySet()) {
    if (!TopicName.isValid(topic.trim())) {
        throw new IllegalArgumentException("Invalid input topic: " + topic);
    }
}

Type guard

boolean isValidPulsarTopic(String t) {
    return t != null && TopicName.isValid(t.trim());
}

Try / catch

try {
    admin.functions().createFunction(functionConfig, sourceConfigLocation);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Input topic")) {
        // inspect config.getInput() topic names and correct fully-qualified form
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling createFunction/updateFunction (or submitting a function via CLI, REST admin API, or function mesh manifests) with a FunctionConfig whose input topics include a string that TopicName.isValid rejects: a bare local topic like 'my-topic' without a tenant/namespace, a name with illegal characters or empty segments, or an empty/whitespace string in the input collection.

Common situations: Config mistakes such as writing 'persistent://my-tenant/my-ns' with a trailing slash, forgetting the tenant/namespace prefix, copy-pasting topic names with trailing whitespace or newline from YAML/env vars, using Kafka-style names in Pulsar, or typos like double colons in the persistent:// URL.

Related errors


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