apache/pulsar · error · IllegalArgumentException

LogTopic topic %s is invalid

Error message

LogTopic topic %s is invalid

What it means

When a function's log topic is set, doCommonChecks requires it to be a valid Pulsar topic name; otherwise the function is rejected with this IllegalArgumentException. The log topic receives all log messages produced by the function's log() calls, so it must be addressable by the Pulsar client.

Source

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

        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())) {
            if (!TopicName.isValid(functionConfig.getDeadLetterTopic())) {
                throw new IllegalArgumentException(
                        String.format("DeadLetter topic %s is invalid", functionConfig.getDeadLetterTopic()));
            }
        }

        if (functionConfig.getParallelism() != null && functionConfig.getParallelism() <= 0) {
            throw new IllegalArgumentException("Function parallelism must be a positive number");
        }
        // Ensure that topics aren't being used as both input and output
        verifyNoTopicClash(allInputTopics, functionConfig.getOutput());

        WindowConfig windowConfig = functionConfig.getWindowConfig();

View on GitHub (pinned to 820761864e)

Solutions

  1. Use a fully qualified topic: persistent://public/default/function-logs
  2. Clear the log-topic field if log collection is not needed
  3. Ensure the tenant/namespace in the log topic exists in the target cluster
  4. Trim the value and re-validate with TopicName.isValid before submit

Example fix

// before
config.setLogTopic("fn-logs");
// after
config.setLogTopic("persistent://public/default/fn-logs");
Defensive patterns

Strategy: validation

Validate before calling

String logTopic = config.getLogTopic();
if (logTopic != null && !logTopic.isEmpty() && !TopicName.isValid(logTopic.trim())) {
    throw new IllegalArgumentException("Invalid log topic: " + logTopic);
}

Type guard

boolean hasValidLogTopic(FunctionConfig c) {
    String t = c.getLogTopic();
    return t == null || t.isEmpty() || TopicName.isValid(t.trim());
}

Try / catch

try {
    admin.functions().createFunction(functionConfig, sourceConfigLocation);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("LogTopic")) {
        // correct config.getLogTopic() or drop it
    }
    throw e;
}

Prevention

When it happens

Trigger: createFunction/updateFunction with functionConfig.getLogTopic() non-empty and TopicName.isValid(logTopic) false: e.g. 'logs' bare name, 'persistent://tenant/ns/' with empty topic segment, or whitespace-padded string from YAML.

Common situations: Enabling function logging via CLI (--log-topic) with a shorthand name, copying the field from another cluster config with different defaults, YAML indentation issues yielding malformed strings.

Related errors


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