{"record":{"id":"9186721e47164352","repo":"provectus/kafka-ui","slug":"connector-with-name-s-already-exists","errorCode":null,"errorMessage":"Connector with name %s already exists","messagePattern":"Connector with name (.+?) already exists","errorType":"validation","errorClass":"ValidationException","httpStatus":400,"severity":"error","filePath":"kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/KafkaConnectService.java","lineNumber":135,"sourceCode":"  public Flux<String> getConnectorNamesWithErrorsSuppress(KafkaCluster cluster, String connectName) {\n    return getConnectorNames(cluster, connectName).onErrorComplete();\n  }\n\n  @SneakyThrows\n  private List<String> parseConnectorsNamesStringToList(String json) {\n    return objectMapper.readValue(json, new TypeReference<>() {\n    });\n  }\n\n  public Mono<ConnectorDTO> createConnector(KafkaCluster cluster, String connectName,\n                                            Mono<NewConnectorDTO> connector) {\n    return api(cluster, connectName)\n        .mono(client ->\n            connector\n                .flatMap(c -> connectorExists(cluster, connectName, c.getName())\n                    .map(exists -> {\n                      if (Boolean.TRUE.equals(exists)) {\n                        throw new ValidationException(\n                            String.format(\"Connector with name %s already exists\", c.getName()));\n                      }\n                      return c;\n                    }))\n                .map(kafkaConnectMapper::toClient)\n                .flatMap(client::createConnector)\n                .flatMap(c -> getConnector(cluster, connectName, c.getName()))\n        );\n  }\n\n  private Mono<Boolean> connectorExists(KafkaCluster cluster, String connectName,\n                                        String connectorName) {\n    return getConnectorNames(cluster, connectName)\n        .any(name -> name.equals(connectorName));\n  }\n\n  public Mono<ConnectorDTO> getConnector(KafkaCluster cluster, String connectName,\n                                         String connectorName) {","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/provectus/kafka-ui/blob/83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7/kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/KafkaConnectService.java#L117-L153","documentation":"KafkaConnectService.createConnector validates that a connector with the same name does not already exist on the target Kafka Connect cluster before delegating to the Connect REST API's createConnector call. Kafka Connect itself rejects duplicate connector names, so kafka-ui pre-checks via connectorExists and fails fast with a ValidationException instead of surfacing an opaque 409 from the Connect API. The message includes the connector name taken from the request body.","triggerScenarios":"POSTing to the create-connector endpoint (POST /api/clusters/{clusterName}/connects/{connectName}/connectors) when a connector with the submitted 'name' already exists on that Connect cluster; also triggered by retrying a create request that succeeded on a previous attempt.","commonSituations":"Re-running a connector creation after an earlier attempt partially succeeded; copying an existing connector config and forgetting to change the name; multiple team members provisioning the same connector concurrently; CI/CD pipelines that are not idempotent and re-register connectors on every deploy.","solutions":["Check the existing connector's config first (GET /api/clusters/{cluster}/connects/{connect}/connectors/{name}) and reuse/update it instead of creating a new one.","Use a unique connector name in the request payload.","Make automation idempotent: delete the existing connector before recreating, or treat the 'already exists' response as success.","If the connector should not exist, delete it via the UI or DELETE .../connectors/{name} before re-creating."],"exampleFix":"// before\n{\n  \"name\": \"orders-sink\",\n  \"config\": { \"connector.class\": \"io.debezium.connector.postgresql.PostgresConnector\", ... }\n}\n// after\n{\n  \"name\": \"orders-sink-v2\",\n  \"config\": { \"connector.class\": \"io.debezium.connector.postgresql.PostgresConnector\", ... }\n}","handlingStrategy":"validation","validationCode":"const exists = await fetch(`/api/clusters/${cluster}/connects/${connect}/connectors/${name}`).then(r => r.status !== 404);\nif (exists) throw new Error(`Connector ${name} already exists — reuse or rename it`);","typeGuard":null,"tryCatchPattern":"try {\n  await createConnector(cluster, connect, payload);\n} catch (e) {\n  if (e.message.includes('already exists')) {\n    // treat as idempotent success or update the existing connector\n  } else { throw e; }\n}","preventionTips":["Make connector provisioning idempotent: check existence before create, or update-if-exists.","Adopt a naming convention with environment/pipeline suffixes to avoid collisions.","In CI/CD, don't blindly re-run create steps; use upsert semantics."],"tags":["kafka-connect","connector","duplicate-resource","validation"],"backgroundTag":"file-already-exists","analyzedSha":"83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7","analyzedAt":"2026-09-08T04:35:39.002Z","contentChangedAt":"2026-09-08T04:35:39.002Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}