apache/pulsar · error · RestException

%s %s already exists

Error message

%s %s already exists

What it means

registerFunction checks the worker's FunctionMetaDataManager for an existing function with the same tenant/namespace/name and rejects duplicate registration with HTTP 400 '<ComponentType> <name> already exists' (e.g. 'Function exclamation already exists'). Function names are unique keys within a tenant/namespace.

Source

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

        } catch (PulsarAdminException.NotFoundException e) {
            log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", functionName)

                    .attr("tenant3", tenant).log("/ / Tenant does not exist");
            throw new RestException(Response.Status.BAD_REQUEST, "Tenant does not exist");
        } catch (PulsarAdminException e) {
            log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", functionName)

                    .exception(e).log("/ / Issues getting tenant data");
            throw new RestException(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage());
        }

        FunctionMetaDataManager functionMetaDataManager = worker().getFunctionMetaDataManager();

        if (functionMetaDataManager.containsFunction(tenant, namespace, functionName)) {
            log.error().attr("componentType", ComponentTypeUtils.toString(componentType)).attr("tenant", tenant)

                    .attr("namespace", namespace).attr("componentName", functionName).log("/ / already exists");
            throw new RestException(Response.Status.BAD_REQUEST, String.format("%s %s already exists",
                    ComponentTypeUtils.toString(componentType), functionName));
        }

        FunctionDetails functionDetails;
        File componentPackageFile = null;
        try {

            // validate parameters
            try {
                if (isNotBlank(functionPkgUrl)) {
                    componentPackageFile = getPackageFile(componentType, functionPkgUrl);
                    functionDetails = validateUpdateRequestParams(tenant, namespace, functionName,
                            functionConfig, componentPackageFile);
                } else {
                    if (uploadedInputStream != null) {
                        componentPackageFile = WorkerUtils.dumpToTmpFile(uploadedInputStream);
                    }
                    functionDetails = validateUpdateRequestParams(tenant, namespace, functionName,

View on GitHub (pinned to 820761864e)

Solutions

  1. Use the update API ('pulsar-admin functions update' or admin.functions().updateFunction) for existing components
  2. Delete the existing function first ('pulsar-admin functions delete') if replacement via create is intended
  3. Choose a unique functionName, or list existing functions ('pulsar-admin functions list') to check availability before creating

Example fix

// before
admin.functions().createFunction(tenant, ns, name, pkgUrl, cfg, null); // exists
// after
admin.functions().updateFunction(tenant, ns, name, pkgUrl, cfg, null);
Defensive patterns

Strategy: try-catch

Validate before calling

boolean exists = admin.functions().getFunctions(tenant, namespace).contains(functionName);
if (exists) { admin.functions().updateFunction(tenant, namespace, functionName, pkgUrl, cfg, null); }
else { admin.functions().createFunction(tenant, namespace, functionName, pkgUrl, cfg, null); }

Try / catch

try { admin.functions().createFunction(...); }
catch (PulsarAdminException e) {
    if (e.getStatusCode() == 400 && String.valueOf(e.getMessage()).contains("already exists")) {
        admin.functions().updateFunction(tenant, namespace, functionName, pkgUrl, cfg, null);
    }
}

Prevention

When it happens

Trigger: POSTing a registration for a function name that already exists in that tenant/namespace — re-running a provisioning script, or conflicting with an existing function/sink/source entry with the same name.

Common situations: CI/CD job replaying a create call instead of update; tenant/namespace reused where the name is already taken; confusion between create (registerFunction) and update (updateFunction) endpoints.

Related errors


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