{"record":{"id":"a41d8305e4b2538b","repo":"apache/pulsar","slug":"package-url-packagepath-is-not-valid","errorCode":null,"errorMessage":"Package URL ${packagePath} is not valid","messagePattern":"Package URL (.+?) is not valid","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/FunctionActioner.java","lineNumber":165,"sourceCode":"                    .getFunctionMetaData().getFunctionDetails();\n            log.error().attr(\"tenant\", details.getTenant())\n                    .attr(\"namespace\", details.getNamespace())\n                    .attr(\"functionName\", details.getName())\n                    .exception(ex).log(\"Error starting function\");\n            functionRuntimeInfo.setStartupException(ex);\n        }\n    }\n\n    private String getPackageFile(FunctionMetaData functionMetaData, FunctionDetails functionDetails, int instanceId,\n                                  PackageLocationMetaData pkgLocation,\n                                  FunctionDetails.ComponentType componentType)\n            throws URISyntaxException, IOException, ClassNotFoundException, PulsarAdminException {\n        String packagePath = pkgLocation.getPackagePath();\n        boolean isPkgUrlProvided = isFunctionPackageUrlSupported(packagePath);\n        String packageFile;\n        if (isPkgUrlProvided && packagePath.startsWith(FILE)) {\n            if (!packageUrlValidator.isValidPackageUrl(componentType, packagePath)) {\n                throw new IllegalArgumentException(\"Package URL \" + packagePath + \" is not valid\");\n            }\n            URL url = new URL(packagePath);\n            File pkgFile = new File(url.toURI());\n            packageFile = pkgFile.getAbsolutePath();\n        } else if (FunctionCommon.isFunctionCodeBuiltin(functionDetails, componentType)) {\n            FunctionDetails functionDetailsCopy = new FunctionDetails();\n            functionDetailsCopy.copyFrom(functionMetaData.getFunctionDetails());\n            File pkgFile = getBuiltinArchive(componentType, functionDetailsCopy);\n            packageFile = pkgFile.getAbsolutePath();\n        } else {\n            File pkgDir = new File(workerConfig.getDownloadDirectory(),\n                    getDownloadPackagePath(functionMetaData, instanceId));\n            pkgDir.mkdirs();\n            File pkgFile = new File(\n                    pkgDir,\n                    new File(getDownloadFileName(functionMetaData.getFunctionDetails(),\n                            pkgLocation)).getName());\n            downloadFile(pkgFile, isPkgUrlProvided, functionMetaData, instanceId, pkgLocation, componentType);","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/FunctionActioner.java#L147-L183","documentation":"FunctionActioner.getPackageFile validates a function's package URL (file:// scheme) before converting it to a local file path. If PackageUrlValidator.isValidPackageUrl rejects the URL, an IllegalArgumentException is thrown and the function fails to start.","triggerScenarios":"Starting a function whose PackageLocationMetadata.packagePath is a file:// URL that fails validation (disallowed scheme characters, path outside allowed roots, malformed URL).","commonSituations":"Hand-edited function configs with a bad file:// path; uploading functions referencing worker-inaccessible local paths; path traversal or non-jar artifacts rejected by the validator.","solutions":["Fix the packagePath to a valid, well-formed file:// URL pointing to an existing function jar","Upload the package via Pulsar's package management service (or HTTP) instead of a raw file URL","Check worker configuration for allowed package URL rules and align the path with them"],"exampleFix":"// before\npkgLocation.setPackagePath(\"file:///opt/../funcs/my-func.jar\"); // rejected\n// after\npkgLocation.setPackagePath(\"file:///pulsar/functions/my-func.jar\");","handlingStrategy":"validation","validationCode":"String path = pkgLocation.getPackagePath();\nif (path != null && path.startsWith(\"file:\")) {\n    try {\n        File f = new File(new URL(path).toURI());\n        if (!f.isFile()) throw new IllegalArgumentException(\"package file missing: \" + f);\n    } catch (URISyntaxException | MalformedURLException e) {\n        throw new IllegalArgumentException(\"bad package URL: \" + path, e);\n    }\n}","typeGuard":"boolean isValidFilePackageUrl(String path) {\n    if (path == null || !path.startsWith(\"file:\")) return false;\n    try { return new File(new URL(path).toURI()).isFile(); }\n    catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n    functionActioner.startFunction(...);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Package URL\")) {\n        // resubmit function with corrected packagePath\n    } else { throw e; }\n}","preventionTips":["Always create function packages via the Pulsar admin/CLI, not hand-written URLs","Normalize paths (no .., no spaces) before building file:// URLs","Ensure the file exists and is readable on every worker host"],"tags":["pulsar-functions","worker","package-url","validation"],"backgroundTag":"invalid-package-url","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}