{"record":{"id":"cd15c3cb70f0f35a","repo":"apache/pulsar","slug":"function-package-url-is-not-valid-supported-url-h","errorCode":null,"errorMessage":"Function Package url is not valid.supported url (http/https/file)","messagePattern":"Function Package url is not valid\\.supported url \\(http/https/file\\)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/ComponentImpl.java","lineNumber":1930,"sourceCode":"        } else {\n            // use the Nar extraction directory as a temporary directory for downloaded files\n            tempDirectory = Paths.get(worker.getWorkerConfig().getNarExtractionDirectory());\n        }\n        Files.createDirectories(tempDirectory);\n        File file = Files.createTempFile(tempDirectory, \"function\", \".tmp\").toFile();\n        worker.getBrokerAdmin().packages().download(packageName, file.toString());\n        return file;\n    }\n\n    protected File getPackageFile(FunctionDetails.ComponentType componentType, String functionPkgUrl,\n                                  String existingPackagePath, InputStream uploadedInputStream)\n            throws IOException, PulsarAdminException {\n        File componentPackageFile = null;\n        if (isNotBlank(functionPkgUrl)) {\n            componentPackageFile = getPackageFile(componentType, functionPkgUrl);\n        } else if (existingPackagePath.startsWith(Utils.FILE) || existingPackagePath.startsWith(Utils.HTTP)) {\n            if (!worker().getPackageUrlValidator().isValidPackageUrl(componentType, existingPackagePath)) {\n                throw new IllegalArgumentException(\"Function Package url is not valid.\"\n                        + \"supported url (http/https/file)\");\n            }\n            try {\n                componentPackageFile = FunctionCommon.extractFileFromPkgURL(existingPackagePath);\n            } catch (Exception e) {\n                throw new IllegalArgumentException(String.format(\"Encountered error \\\"%s\\\" \"\n                                + \"when getting %s package from %s\", e.getMessage(),\n                        ComponentTypeUtils.toString(componentType), existingPackagePath));\n            }\n        } else if (Utils.hasPackageTypePrefix(existingPackagePath)) {\n            componentPackageFile = getPackageFile(componentType, existingPackagePath);\n        } else if (uploadedInputStream != null) {\n            componentPackageFile = WorkerUtils.dumpToTmpFile(uploadedInputStream);\n        } else if (!existingPackagePath.startsWith(Utils.BUILTIN)) {\n            componentPackageFile = FunctionCommon.createPkgTempFile();\n            componentPackageFile.deleteOnExit();\n            if (worker().getWorkerConfig().isFunctionsWorkerEnablePackageManagement()) {\n                worker().getBrokerAdmin().packages().download(","sourceCodeStart":1912,"sourceCodeEnd":1948,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/ComponentImpl.java#L1912-L1948","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Prefix local paths with file:// (e.g. file:///path/to/function.jar) or serve the package over http:// or https://.","If the package lives in a package management service, use the package:// URL form (with functionsWorkerEnablePackageManagement=true) instead of a raw path.","Check the worker's PackageUrlValidator configuration to confirm which schemes it accepts.","If the package should be newly uploaded, pass it via functionPkgUrl or the uploaded input stream instead of existingPackagePath."],"exampleFix":"// before\nString existingPackagePath = \"/opt/pulsar/functions/exclamation.jar\";\nadmin.functions().updateFunction(tenant, namespace, name, functionConfig);\n// after\nString existingPackagePath = \"file:///opt/pulsar/functions/exclamation.jar\";\nadmin.functions().updateFunction(tenant, namespace, name, functionConfig);","handlingStrategy":"validation","validationCode":"boolean isValidExistingPackage(String p) {\n    return p != null && (p.startsWith(\"file://\") || p.startsWith(\"http://\") || p.startsWith(\"https://\"));\n}\nif (!isValidExistingPackage(existingPackagePath)) {\n    throw new IllegalArgumentException(\"existingPackagePath must start with http://, https://, or file://: \" + existingPackagePath);\n}","typeGuard":null,"tryCatchPattern":"try {\n    admin.functions().updateFunction(tenant, namespace, name, config);\n} catch (PulsarAdminException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"not valid\")) {\n        // surface a client-side URL-scheme validation error\n    }\n    throw e;\n}","preventionTips":["Always prefix local paths with file:// when reusing an existing package.","Only use http:// or https:// URLs hosted somewhere the worker can reach.","Keep a client-side scheme check before every admin API call.","If using package://, confirm the worker has package management enabled instead."],"tags":["url-validation","pulsar-functions","illegal-argument"],"backgroundTag":"unsupported-package-url","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"}