apache/pulsar · error · IllegalArgumentException

Function Package url is not valid.supported url (http/https/

Error message

Function Package url is not valid.supported url (http/https/file)

What it means

Thrown as IllegalArgumentException when registering/updating a function, sink, or source with an existingPackagePath whose URL scheme is neither http(s) nor file (e.g. it has no package-type prefix and fails the PackageUrlValidator). The worker refuses to fetch a package from an unsupported location because it cannot extract the component archive from such a URL.

Source

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

        } else {
            // use the Nar extraction directory as a temporary directory for downloaded files
            tempDirectory = Paths.get(worker.getWorkerConfig().getNarExtractionDirectory());
        }
        Files.createDirectories(tempDirectory);
        File file = Files.createTempFile(tempDirectory, "function", ".tmp").toFile();
        worker.getBrokerAdmin().packages().download(packageName, file.toString());
        return file;
    }

    protected File getPackageFile(FunctionDetails.ComponentType componentType, String functionPkgUrl,
                                  String existingPackagePath, InputStream uploadedInputStream)
            throws IOException, PulsarAdminException {
        File componentPackageFile = null;
        if (isNotBlank(functionPkgUrl)) {
            componentPackageFile = getPackageFile(componentType, functionPkgUrl);
        } else if (existingPackagePath.startsWith(Utils.FILE) || existingPackagePath.startsWith(Utils.HTTP)) {
            if (!worker().getPackageUrlValidator().isValidPackageUrl(componentType, existingPackagePath)) {
                throw new IllegalArgumentException("Function Package url is not valid."
                        + "supported url (http/https/file)");
            }
            try {
                componentPackageFile = FunctionCommon.extractFileFromPkgURL(existingPackagePath);
            } catch (Exception e) {
                throw new IllegalArgumentException(String.format("Encountered error \"%s\" "
                                + "when getting %s package from %s", e.getMessage(),
                        ComponentTypeUtils.toString(componentType), existingPackagePath));
            }
        } else if (Utils.hasPackageTypePrefix(existingPackagePath)) {
            componentPackageFile = getPackageFile(componentType, existingPackagePath);
        } else if (uploadedInputStream != null) {
            componentPackageFile = WorkerUtils.dumpToTmpFile(uploadedInputStream);
        } else if (!existingPackagePath.startsWith(Utils.BUILTIN)) {
            componentPackageFile = FunctionCommon.createPkgTempFile();
            componentPackageFile.deleteOnExit();
            if (worker().getWorkerConfig().isFunctionsWorkerEnablePackageManagement()) {
                worker().getBrokerAdmin().packages().download(

View on GitHub (pinned to 820761864e)

Solutions

  1. Prefix local paths with file:// (e.g. file:///path/to/function.jar) or serve the package over http:// or https://.
  2. If the package lives in a package management service, use the package:// URL form (with functionsWorkerEnablePackageManagement=true) instead of a raw path.
  3. Check the worker's PackageUrlValidator configuration to confirm which schemes it accepts.
  4. If the package should be newly uploaded, pass it via functionPkgUrl or the uploaded input stream instead of existingPackagePath.

Example fix

// before
String existingPackagePath = "/opt/pulsar/functions/exclamation.jar";
admin.functions().updateFunction(tenant, namespace, name, functionConfig);
// after
String existingPackagePath = "file:///opt/pulsar/functions/exclamation.jar";
admin.functions().updateFunction(tenant, namespace, name, functionConfig);
Defensive patterns

Strategy: validation

Validate before calling

boolean isValidExistingPackage(String p) {
    return p != null && (p.startsWith("file://") || p.startsWith("http://") || p.startsWith("https://"));
}
if (!isValidExistingPackage(existingPackagePath)) {
    throw new IllegalArgumentException("existingPackagePath must start with http://, https://, or file://: " + existingPackagePath);
}

Try / catch

try {
    admin.functions().updateFunction(tenant, namespace, name, config);
} catch (PulsarAdminException e) {
    if (e.getMessage() != null && e.getMessage().contains("not valid")) {
        // surface a client-side URL-scheme validation error
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling the Functions/Sinks/Sources admin REST API (registerFunction/updateFunction or equivalents via ComponentImpl) with a blank functionPkgUrl and an existingPackagePath that does not start with Utils.FILE ('file://') or Utils.HTTP ('http://' or 'https://') and fails worker().getPackageUrlValidator().isValidPackageUrl — e.g. a bare relative path like '/local/dir/my.jar' without scheme, 'ftp://host/pkg.jar', or a misspelled scheme.

Common situations: Copy-pasting a local filesystem path into existingPackagePath without the file:// prefix; using a scheme other than http/https/file; upgrading Pulsar and a custom PackageUrlValidator now rejecting previously accepted URLs; confusing existingPackagePath (reused package) with functionPkgUrl (upload).

Related errors


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