apache/pulsar · error · IllegalArgumentException

Built-in source is not available

Error message

Built-in source is not available

What it means

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).

Source

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

                                                                 final SourceConfig sourceConfig,
                                                                 final File sourcePackageFile) {
        // The rest end points take precedence over whatever is there in sourceconfig
        sourceConfig.setTenant(tenant);
        sourceConfig.setNamespace(namespace);
        sourceConfig.setName(sourceName);
        org.apache.pulsar.common.functions.Utils.inferMissingArguments(sourceConfig);

        ValidatableFunctionPackage connectorFunctionPackage = null;
        // check if source is builtin and extract classloader
        if (!StringUtils.isEmpty(sourceConfig.getArchive())) {
            String archive = sourceConfig.getArchive();
            if (archive.startsWith(org.apache.pulsar.common.functions.Utils.BUILTIN)) {
                archive = archive.replaceFirst("^builtin://", "");

                Connector connector = worker().getConnectorsManager().getConnector(archive);
                // check if builtin connector exists
                if (connector == null) {
                    throw new IllegalArgumentException("Built-in source is not available");
                }
                connectorFunctionPackage = connector.getConnectorFunctionPackage();
            }
        }

        boolean shouldCloseFunctionPackage = false;
        try {
            // if source is not builtin, attempt to extract classloader from package file if it exists
            WorkerConfig workerConfig = worker().getWorkerConfig();
            if (connectorFunctionPackage == null && sourcePackageFile != null) {
                connectorFunctionPackage =
                        new FunctionFilePackage(sourcePackageFile, workerConfig.getNarExtractionDirectory(),
                                workerConfig.getEnableClassloadingOfExternalFiles(), ConnectorDefinition.class);
                shouldCloseFunctionPackage = true;
            }

            if (connectorFunctionPackage == null) {
                throw new IllegalArgumentException("Source package is not provided");

View on GitHub (pinned to 820761864e)

Solutions

  1. List available connectors (GET /connectors) and use an exact matching name
  2. Copy the connector NAR into the worker's connectorsDirectory and restart the worker
  3. Ensure the name after 'builtin://' is correct (exact case, no extra path elements)
  4. If not using a builtin connector, supply the actual package file/URL instead

Example fix

// before
sourceConfig.setArchive("builtin://kafka-soure"); // typo
// after
sourceConfig.setArchive("builtin://kafka"); // exact connector name from GET /connectors
Defensive patterns

Strategy: validation

Validate before calling

String archive = sourceConfig.getArchive();
if (archive != null && archive.startsWith("builtin://")) {
    String n = archive.replaceFirst("^builtin://", "");
    if (!admin.sources().getSources().contains(n)) {
        throw new IllegalArgumentException("builtin source missing: " + n);
    }
}

Type guard

boolean isValidBuiltinArchive(PulsarAdmin admin, String archive) {
    if (archive == null || !archive.startsWith("builtin://")) return archive != null;
    try { return admin.sources().getSources().contains(archive.replaceFirst("^builtin://", "")); }
    catch (PulsarAdminException e) { return false; }
}

Try / catch

try {
    admin.sources().updateSource(tn, ns, name, cfg, null);
} catch (PulsarAdminException e) {
    if (e.getMessage() != null && e.getMessage().contains("Built-in source is not available")) {
        // correct the archive name or deploy the connector NAR
    }
    throw e;
}

Prevention

When it happens

Trigger: registerSource/updateSource with packageLocation or archive equal to 'builtin://<name>' where <name> does not match any connector NAR loaded by the worker.

Common situations: 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.

Related errors


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