apache/pulsar · error · RestException

Function %s doesn't exist

Error message

Function %s doesn't exist

What it means

After validation, triggerFunction checks FunctionMetaDataManager.containsFunction. If no function with the given tenant/namespace/name exists in the worker's metadata, it returns HTTP 404 Not Found with 'Function <name> doesn't exist'. The trigger never reaches the topic machinery.

Source

Thrown at pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/ComponentImpl.java:1127

        throwRestExceptionIfUnauthorizedForNamespace(tenant, namespace, functionName, "trigger", authParams);

        // validate parameters
        try {
            validateTriggerRequestParams(tenant, namespace, functionName, topic, input, uploadedInputStream);
        } catch (IllegalArgumentException e) {
            log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", functionName)

                    .exception(e).log("Invalid trigger function request @ / / /");
            throw new RestException(Status.BAD_REQUEST, e.getMessage());
        }

        FunctionMetaDataManager functionMetaDataManager = worker().getFunctionMetaDataManager();
        if (!functionMetaDataManager.containsFunction(tenant, namespace, functionName)) {
            log.warn().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", functionName)

                    .log("Function in trigger function does not exist @ / / /");
            throw new RestException(Status.NOT_FOUND, String.format("Function %s doesn't exist", functionName));
        }

        FunctionMetaData functionMetaData = functionMetaDataManager.getFunctionMetaData(tenant, namespace,
                functionName);

        String inputTopicToWrite;
        if (topic != null) {
            inputTopicToWrite = topic;
        } else if (functionMetaData.getFunctionDetails().getSource().getInputSpecsCount() == 1) {
            String[] firstKey = new String[1];
            functionMetaData.getFunctionDetails().getSource().forEachInputSpecs((k, v) -> firstKey[0] = k);
            inputTopicToWrite = firstKey[0];
        } else {
            log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", functionName)

                    .log("Function in trigger function has more than 1 input topics @ / / /");
            throw new RestException(Status.BAD_REQUEST, "Function in trigger function has more than 1 input topics");
        }

View on GitHub (pinned to 820761864e)

Solutions

  1. List functions in the tenant/namespace (GET /functions/{tenant}/{namespace}) and confirm the exact function name.
  2. Correct tenant/namespace/functionName in the trigger URL — names are case-sensitive.
  3. Retry after a short delay if the function was just submitted (metadata propagation).
  4. Re-submit the function if it was deleted, then trigger again.

Example fix

// before
curl -X POST --data-binary 'x' .../functions/public/default/exFunc  # wrong case
// after
curl -X POST --data-binary 'x' .../functions/public/default/exfunc  # matches registered name
Defensive patterns

Strategy: validation

Validate before calling

import java.util.List;
static boolean functionExists(Functions functions, String t, String n, String fn) throws PulsarAdminException {
  return functions.getFunctions(t, n).contains(fn);
}

Try / catch

try { trigger(...); }
catch (PulsarAdminException e) {
  if (e.getResponseStatus() == 404)
    throw new IllegalStateException("Function " + fn + " not registered in " + t + "/" + n);
  throw e;
}

Prevention

When it happens

Trigger: POST trigger for a function name that was never submitted, was deleted, or is registered under a different tenant/namespace; also triggered while function metadata has not yet propagated to the worker handling the request.

Common situations: Typo in the function name; triggering in the wrong tenant/namespace; calling trigger immediately after submission before metadata sync; function deleted by a concurrent pipeline run.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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