apache/pulsar · error · IllegalArgumentException

Transform Function package not found

Error message

Transform Function package not found

What it means

If sinkConfig references a transformFunction (builtin or uploaded), the worker resolves its package. When all resolution paths fail and transformFunctionPackage is still null, validateUpdateRequestParams throws IllegalArgumentException('Transform Function package not found').

Solutions

  1. Verify the transform function package exists via the Functions package management API (function://tenant/ns/name@version).
  2. Upload the transform function first (pulsar-admin packages upload function://...) and reference that exact URL.
  3. Or upload the transform function package file directly in the sink create/update request.
  4. Remove the transformFunction from the sink config if it is not actually needed.

Example fix

// before
sinkConfig.setTransformFunction("my-transform"); // not resolvable
// after: reference an uploaded package
pulsar-admin packages upload function://public/default/my-transform@1.0 --path transform.jar
sinkConfig.setTransformFunction("function://public/default/my-transform@1.0");
Defensive patterns

Strategy: validation

Validate before calling

String tf = sinkConfig.getTransformFunction();
if (tf != null && !tf.startsWith("function://")) {
    boolean exists = admin.packages().listPackages("function://" + tenant + "/" + ns).stream().anyMatch(tf::endsWith);
    if (!exists) throw new IllegalStateException("transform package missing: " + tf);
}

Type guard

boolean isPackageUrl(String s) { return s != null && s.matches("function://[^/]+/[^/]+/[^@]+@.+"); }

Try / catch

try { admin.sinks().updateSink(...); } catch (PulsarAdminException e) { if (e.getMessage() != null && e.getMessage().contains("Transform Function package not found")) { /* upload transform package */ } throw e; }

Prevention

When it happens

Trigger: registerSink/updateSink with sinkConfig.setTransformFunction("<name>") where the name is neither resolvable as a built-in/registered function package (getBuiltinFunctionPackage returns null) nor accompanied by a valid functionPackageFile upload.

Common situations: Transform function name typo; transform function not uploaded to the package management service; referencing a transform by class name instead of package name; package uploaded to a different tenant/namespace than referenced in config.

Related errors


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

Appendix: source

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

            }

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

            if (isNotBlank(sinkConfig.getTransformFunction())) {
                transformFunctionPackage =
                        getBuiltinFunctionPackage(sinkConfig.getTransformFunction());
                if (transformFunctionPackage == null) {
                    File functionPackageFile = getPackageFile(FunctionDetails.ComponentType.FUNCTION,
                            sinkConfig.getTransformFunction());
                    transformFunctionPackage =
                            new FunctionFilePackage(functionPackageFile, workerConfig.getNarExtractionDirectory(),
                                    workerConfig.getEnableClassloadingOfExternalFiles(), ConnectorDefinition.class);
                    shouldCloseTransformFunctionPackage = true;
                }
                if (transformFunctionPackage == null) {
                    throw new IllegalArgumentException("Transform Function package not found");
                }
            }

            SinkConfigUtils.ExtractedSinkDetails sinkDetails =
                    SinkConfigUtils.validateAndExtractDetails(sinkConfig, connectorFunctionPackage,
                            transformFunctionPackage, workerConfig.getValidateConnectorConfig());

            return SinkConfigUtils.convert(sinkConfig, sinkDetails);
        } finally {
            if (shouldCloseFunctionPackage && connectorFunctionPackage instanceof AutoCloseable) {
                try {
                    ((AutoCloseable) connectorFunctionPackage).close();
                } catch (Exception e) {
                    log.error().exception(e).log("Failed to connector function file");
                }
            }
            if (shouldCloseTransformFunctionPackage && transformFunctionPackage instanceof AutoCloseable) {
                try {

View on GitHub (pinned to 820761864e)