{"record":{"id":"3839259583a9e871","repo":"apache/pulsar","slug":"built-in-source-is-not-available","errorCode":null,"errorMessage":"Built-in source is not available","messagePattern":"Built-in source is not available","errorType":"http","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SourcesImpl.java","lineNumber":722,"sourceCode":"                                                                 final SourceConfig sourceConfig,\n                                                                 final File sourcePackageFile) {\n        // The rest end points take precedence over whatever is there in sourceconfig\n        sourceConfig.setTenant(tenant);\n        sourceConfig.setNamespace(namespace);\n        sourceConfig.setName(sourceName);\n        org.apache.pulsar.common.functions.Utils.inferMissingArguments(sourceConfig);\n\n        ValidatableFunctionPackage connectorFunctionPackage = null;\n        // check if source is builtin and extract classloader\n        if (!StringUtils.isEmpty(sourceConfig.getArchive())) {\n            String archive = sourceConfig.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 source is not available\");\n                }\n                connectorFunctionPackage = connector.getConnectorFunctionPackage();\n            }\n        }\n\n        boolean shouldCloseFunctionPackage = false;\n        try {\n            // if source is not builtin, attempt to extract classloader from package file if it exists\n            WorkerConfig workerConfig = worker().getWorkerConfig();\n            if (connectorFunctionPackage == null && sourcePackageFile != null) {\n                connectorFunctionPackage =\n                        new FunctionFilePackage(sourcePackageFile, workerConfig.getNarExtractionDirectory(),\n                                workerConfig.getEnableClassloadingOfExternalFiles(), ConnectorDefinition.class);\n                shouldCloseFunctionPackage = true;\n            }\n\n            if (connectorFunctionPackage == null) {\n                throw new IllegalArgumentException(\"Source package is not provided\");","sourceCodeStart":704,"sourceCodeEnd":740,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SourcesImpl.java#L704-L740","documentation":"During validateUpdateRequestParams, an archive beginning with builtin:// is resolved against the worker's ConnectorsManager; if no connector with that name is registered, this IllegalArgumentException is thrown (ultimately surfacing as a 400-level REST failure from the register/update call).","triggerScenarios":"registerSource/updateSource with packageLocation or archive equal to 'builtin://<name>' where <name> does not match any connector NAR loaded by the worker.","commonSituations":"Typo in the builtin archive name; connector NAR missing from the worker's connectorsDirectory; connector deployed on brokers but not on the functions worker performing validation; case mismatch in the name.","solutions":["List available connectors (GET /connectors) and use an exact matching name","Copy the connector NAR into the worker's connectorsDirectory and restart the worker","Ensure the name after 'builtin://' is correct (exact case, no extra path elements)","If not using a builtin connector, supply the actual package file/URL instead"],"exampleFix":"// before\nsourceConfig.setArchive(\"builtin://kafka-soure\"); // typo\n// after\nsourceConfig.setArchive(\"builtin://kafka\"); // exact connector name from GET /connectors","handlingStrategy":"validation","validationCode":"String archive = sourceConfig.getArchive();\nif (archive != null && archive.startsWith(\"builtin://\")) {\n    String n = archive.replaceFirst(\"^builtin://\", \"\");\n    if (!admin.sources().getSources().contains(n)) {\n        throw new IllegalArgumentException(\"builtin source missing: \" + n);\n    }\n}","typeGuard":"boolean isValidBuiltinArchive(PulsarAdmin admin, String archive) {\n    if (archive == null || !archive.startsWith(\"builtin://\")) return archive != null;\n    try { return admin.sources().getSources().contains(archive.replaceFirst(\"^builtin://\", \"\")); }\n    catch (PulsarAdminException e) { return false; }\n}","tryCatchPattern":"try {\n    admin.sources().updateSource(tn, ns, name, cfg, null);\n} catch (PulsarAdminException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Built-in source is not available\")) {\n        // correct the archive name or deploy the connector NAR\n    }\n    throw e;\n}","preventionTips":["Copy exact connector names from GET /connectors, never type from memory","Keep connector NARs deployed on functions workers, not just brokers","Watch for case/path mismatches in builtin:// names","Pin connector names in config-as-code with a pre-flight check"],"tags":["pulsar-functions","connectors","builtin-archive","validation"],"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"}