{"record":{"id":"6f161d82ae83a61d","repo":"apache/pulsar","slug":"s-s-already-exists-6f161d","errorCode":null,"errorMessage":"%s %s already exists","messagePattern":"(.+?) (.+?) already exists","errorType":"http","errorClass":"RestException","httpStatus":400,"severity":"error","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SourcesImpl.java","lineNumber":145,"sourceCode":"        } catch (PulsarAdminException.NotFoundException e) {\n            log.error().attr(\"tenant\", tenant).attr(\"namespace\", namespace).attr(\"componentName\", sourceName)\n\n                    .attr(\"tenant3\", tenant).log(\"/ / Tenant does not exist\");\n            throw new RestException(Response.Status.BAD_REQUEST, \"Tenant does not exist\");\n        } catch (PulsarAdminException e) {\n            log.error().attr(\"tenant\", tenant).attr(\"namespace\", namespace).attr(\"componentName\", sourceName)\n\n                    .exception(e).log(\"/ / Issues getting tenant data\");\n            throw new RestException(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage());\n        }\n\n        FunctionMetaDataManager functionMetaDataManager = worker().getFunctionMetaDataManager();\n\n        if (functionMetaDataManager.containsFunction(tenant, namespace, sourceName)) {\n            log.error().attr(\"componentType\", ComponentTypeUtils.toString(componentType)).attr(\"tenant\", tenant)\n\n                    .attr(\"namespace\", namespace).attr(\"componentName\", sourceName).log(\"/ / already exists\");\n            throw new RestException(Response.Status.BAD_REQUEST,\n                    String.format(\"%s %s already exists\", ComponentTypeUtils.toString(componentType), sourceName));\n        }\n\n        FunctionDetails functionDetails = null;\n        boolean isPkgUrlProvided = isNotBlank(sourcePkgUrl);\n        File componentPackageFile = null;\n        try {\n\n            // validate parameters\n            try {\n                if (isPkgUrlProvided) {\n                    componentPackageFile = getPackageFile(componentType, sourcePkgUrl);\n                    functionDetails = validateUpdateRequestParams(tenant, namespace, sourceName,\n                            sourceConfig, componentPackageFile);\n                } else {\n                    if (uploadedInputStream != null) {\n                        componentPackageFile = WorkerUtils.dumpToTmpFile(uploadedInputStream);\n                    }","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SourcesImpl.java#L127-L163","documentation":"Thrown when FunctionMetaDataManager.containsFunction reports a source with the same name already exists in the tenant/namespace. The worker rejects the registration with HTTP 400 BAD_REQUEST because Pulsar treats component names as unique per namespace — you must update, not register.","triggerScenarios":"POSTing a registration for a source whose (tenant, namespace, sourceName) triple already has a registered source; re-running a create script without deleting the old source; accidental name collision between sources and functions in the same namespace.","commonSituations":"CI/CD re-deploying a source with create instead of update; failed previous deployment left the source registered; multiple teams reusing the same source name; copy-pasted configs with an unchanged sourceName.","solutions":["Use the update endpoint/trigger instead of create: pulsar-admin sources update ...","Delete the existing source first: pulsar-admin sources delete --tenant <t> --namespace <ns> --name <name>, then create","List existing sources to check the collision: pulsar-admin sources list --tenant <t> --namespace <ns>","Pick a unique sourceName for the new source"],"exampleFix":"// before\npulsar-admin sources create --tenant public --namespace default --name my-source ... // -> 400 my-source already exists\n// after\npulsar-admin sources update --tenant public --namespace default --name my-source --sourceConfigFile my-source.yaml","handlingStrategy":"validation","validationCode":"try (PulsarAdmin admin = PulsarAdminClient.builder().serviceHttpUrl(adminUrl).build()) {\n    boolean exists = admin.sources().listSources(tenant, namespace)\n            .stream().anyMatch(s -> s.getName().equals(sourceName));\n    if (exists) {\n        admin.sources().updateSource(sourceConfig, pkgUrl, inputStream); // update instead of create\n    } else {\n        admin.sources().createSource(sourceConfig, pkgUrl, inputStream);\n    }\n}","typeGuard":"boolean sourceExists(java.util.List<org.apache.pulsar.common.functions.SourceConfig> configs, String name) {\n    return configs != null && configs.stream().anyMatch(c -> name.equals(c.getName()));\n}","tryCatchPattern":"try {\n    sources.createSource(sourceConfig, pkgUrl, inputStream);\n} catch (PulsarAdminException e) {\n    if (e.getMessage() != null && e.getMessage().endsWith(\"already exists\")) {\n        sources.updateSource(sourceConfig, pkgUrl, inputStream); // idempotent upsert\n    } else { throw e; }\n}","preventionTips":["Prefer update (upsert) semantics in deployment scripts to make them idempotent","Derive sourceName from a unique config value per environment","List sources before create in CI to detect collisions early","Avoid reusing one source name across teams in the same namespace"],"tags":["duplicate","conflict","rest-api","pulsar-functions"],"backgroundTag":"component-already-exists","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}