{"record":{"id":"f598a116e2f9d03a","repo":"apache/pulsar","slug":"built-in-sink-is-not-available","errorCode":null,"errorMessage":"Built-in sink is not available","messagePattern":"Built-in sink is not available","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SinksImpl.java","lineNumber":769,"sourceCode":"            throws IOException, PulsarAdminException {\n\n        // The rest end points take precedence over whatever is there in sinkConfig\n        sinkConfig.setTenant(tenant);\n        sinkConfig.setNamespace(namespace);\n        sinkConfig.setName(sinkName);\n        org.apache.pulsar.common.functions.Utils.inferMissingArguments(sinkConfig);\n\n        ValidatableFunctionPackage connectorFunctionPackage = null;\n        // check if sink is builtin and extract classloader\n        if (!StringUtils.isEmpty(sinkConfig.getArchive())) {\n            String archive = sinkConfig.getArchive();\n            if (archive.startsWith(org.apache.pulsar.common.functions.Utils.BUILTIN)) {\n                archive = archive.replaceFirst(\"^builtin://\", \"\");\n\n                Connector connector = worker().getConnectorsManager().getConnector(archive);\n                // check if builtin connector exists\n                if (connector == null) {\n                    throw new IllegalArgumentException(\"Built-in sink is not available\");\n                }\n                connectorFunctionPackage = connector.getConnectorFunctionPackage();\n            }\n        }\n\n        boolean shouldCloseFunctionPackage = false;\n        ValidatableFunctionPackage transformFunctionPackage = null;\n        boolean shouldCloseTransformFunctionPackage = false;\n        try {\n\n            // if sink is not builtin, attempt to extract classloader from package file if it exists\n            WorkerConfig workerConfig = worker().getWorkerConfig();\n            if (connectorFunctionPackage == null && sinkPackageFile != null) {\n                connectorFunctionPackage =\n                        new FunctionFilePackage(sinkPackageFile, workerConfig.getNarExtractionDirectory(),\n                                workerConfig.getEnableClassloadingOfExternalFiles(), ConnectorDefinition.class);\n                shouldCloseFunctionPackage = true;\n            }","sourceCodeStart":751,"sourceCodeEnd":787,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SinksImpl.java#L751-L787","documentation":"During sink register/update validation, if the archive URL uses the builtin:// scheme, the worker looks the archive name up in its ConnectorsManager. If no matching built-in connector NAR is installed, validateUpdateRequestParams throws IllegalArgumentException('Built-in sink is not available'), which surfaces as an HTTP 400/500 to the client.","triggerScenarios":"registerSink or updateSink with sinkConfig.setArchive(\"builtin://<name>\") where <name> does not match any connector NAR in the worker's connectorsDirectory (typo, wrong version name, or connector simply not installed on the worker).","commonSituations":"Deploying with builtin://jar-name but only the class name was used (builtin archives are referenced by NAR file name); connectors deployed on broker but not on the functions worker; upgrading Pulsar where built-in connector names changed; hand-edited function configs.","solutions":["Check installed connectors via GET /admin/v3/functions/connectors and use the exact archive/NAR name with builtin://.","Install the connector NAR into the worker's connectorsDirectory (and restart the worker).","Alternatively ship your own archive: upload the NAR via the package management API or set archive to a full function package URL instead of builtin://."],"exampleFix":"// before\nsinkConfig.setArchive(\"builtin://kafka\");\n// after: use exact installed NAR name\nsinkConfig.setArchive(\"builtin://pulsar-io-kafka-3.2.0.nar\"); // verify via connectors list API","handlingStrategy":"validation","validationCode":"boolean installed = admin.connectors().getConnectors().stream()\n    .anyMatch(c -> archiveName.equals(c.getName()) || c.getConnectorFunctionPackage().endsWith(archiveName));\nif (!installed) throw new IllegalStateException(\"builtin sink not installed: \" + archiveName);","typeGuard":"boolean isBuiltinArchive(String archive) { return archive != null && archive.startsWith(\"builtin://\"); }","tryCatchPattern":"try { admin.sinks().createSink(...); } catch (PulsarAdminException e) { if (String.valueOf(e.getCause()).contains(\"Built-in sink is not available\")) { /* list connectors, fix archive name */ } throw e; }","preventionTips":["Resolve builtin:// names from the connectors list API","Keep connector NARs deployed on every functions worker","Pin exact NAR file names in deployment manifests","Prefer package-management URLs over builtin:// for custom connectors"],"tags":["validation","connectors","builtin-archive","pulsar-functions"],"backgroundTag":"connector-not-found","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"}