apache/pulsar · error · IllegalArgumentException

Built-in sink is not available

Error message

Built-in sink is not available

What it means

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.

Source

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

            throws IOException, PulsarAdminException {

        // The rest end points take precedence over whatever is there in sinkConfig
        sinkConfig.setTenant(tenant);
        sinkConfig.setNamespace(namespace);
        sinkConfig.setName(sinkName);
        org.apache.pulsar.common.functions.Utils.inferMissingArguments(sinkConfig);

        ValidatableFunctionPackage connectorFunctionPackage = null;
        // check if sink is builtin and extract classloader
        if (!StringUtils.isEmpty(sinkConfig.getArchive())) {
            String archive = sinkConfig.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 sink is not available");
                }
                connectorFunctionPackage = connector.getConnectorFunctionPackage();
            }
        }

        boolean shouldCloseFunctionPackage = false;
        ValidatableFunctionPackage transformFunctionPackage = null;
        boolean shouldCloseTransformFunctionPackage = false;
        try {

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

View on GitHub (pinned to 820761864e)

Solutions

  1. Check installed connectors via GET /admin/v3/functions/connectors and use the exact archive/NAR name with builtin://.
  2. Install the connector NAR into the worker's connectorsDirectory (and restart the worker).
  3. 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://.

Example fix

// before
sinkConfig.setArchive("builtin://kafka");
// after: use exact installed NAR name
sinkConfig.setArchive("builtin://pulsar-io-kafka-3.2.0.nar"); // verify via connectors list API
Defensive patterns

Strategy: validation

Validate before calling

boolean installed = admin.connectors().getConnectors().stream()
    .anyMatch(c -> archiveName.equals(c.getName()) || c.getConnectorFunctionPackage().endsWith(archiveName));
if (!installed) throw new IllegalStateException("builtin sink not installed: " + archiveName);

Type guard

boolean isBuiltinArchive(String archive) { return archive != null && archive.startsWith("builtin://"); }

Try / catch

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; }

Prevention

When it happens

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

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

Related errors


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