{"record":{"id":"b051c090ad60728b","repo":"apache/pulsar","slug":"package-url-pkglocationpath-is-not-valid","errorCode":null,"errorMessage":"Package URL ${pkgLocationPath} 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":273,"sourceCode":"        do {\n            tempPkgFile = new File(\n                    pkgDir,\n                    pkgFile.getName() + \".\" + instanceId + \".\" + UUID.randomUUID());\n        } while (tempPkgFile.exists() || !tempPkgFile.createNewFile());\n        String pkgLocationPath = pkgLocation.getPackagePath();\n        boolean downloadFromHttp = isPkgUrlProvided && pkgLocationPath.startsWith(HTTP);\n        boolean downloadFromPackageManagementService = isPkgUrlProvided && hasPackageTypePrefix(pkgLocationPath);\n        log.info().attr(\"tenant\", details.getTenant())\n                .attr(\"namespace\", details.getNamespace())\n                .attr(\"functionName\", details.getName())\n                .attr(\"pkgFile\", tempPkgFile)\n                .attr(\"source\", downloadFromHttp ? pkgLocationPath : pkgLocation)\n                .log(\"Function package file will be downloaded\");\n\n        long downloadStartMs = System.currentTimeMillis();\n        if (downloadFromHttp) {\n            if (!packageUrlValidator.isValidPackageUrl(componentType, pkgLocationPath)) {\n                throw new IllegalArgumentException(\"Package URL \" + pkgLocationPath + \" is not valid\");\n            }\n            FunctionCommon.downloadFromHttpUrl(pkgLocationPath, tempPkgFile);\n        } else if (downloadFromPackageManagementService) {\n            getPulsarAdmin().packages().download(pkgLocationPath, tempPkgFile.getPath());\n        } else {\n            try (FileOutputStream tempPkgFos = new FileOutputStream(tempPkgFile)) {\n                WorkerUtils.downloadFromBookkeeper(\n                        dlogNamespace,\n                        tempPkgFos,\n                        pkgLocationPath);\n            }\n        }\n        log.info().attr(\"tenant\", details.getTenant())\n                .attr(\"namespace\", details.getNamespace())\n                .attr(\"functionName\", details.getName())\n                .attr(\"pkgFile\", tempPkgFile)\n                .attr(\"sizeBytes\", tempPkgFile.length())\n                .attr(\"durationMs\", System.currentTimeMillis() - downloadStartMs)","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/FunctionActioner.java#L255-L291","documentation":"FunctionActioner.downloadFile downloads the function package from an HTTP URL and validates the URL first. If PackageUrlValidator.isValidPackageUrl rejects the http(s) URL, an IllegalArgumentException is thrown before any download happens.","triggerScenarios":"Downloading a function package whose packagePath is an http(s) URL that fails validation (malformed URL, disallowed host/scheme, path traversal).","commonSituations":"Typos in the package URL; pointing at an untrusted or non-whitelisted host; URL-encoding issues in the package path stored in function metadata.","solutions":["Correct the package URL in the function metadata to a valid http(s) URL","Use Pulsar package management service URLs (as an alternative branch, no HTTP validation needed)","Review worker's package URL validator configuration for what is accepted"],"exampleFix":"// before\npkgLocation.setPackagePath(\"http:/bad-host/func.jar\"); // throws\n// after\npkgLocation.setPackagePath(\"https://broker.example.com/functions/my-func.jar\");","handlingStrategy":"validation","validationCode":"String url = pkgLocation.getPackagePath();\nif (url != null && (url.startsWith(\"http:\") || url.startsWith(\"https:\"))) {\n    try {\n        new java.net.URL(url).openConnection().connect(); // reachable check\n    } catch (IOException e) {\n        throw new IllegalArgumentException(\"package URL unreachable/invalid: \" + url, e);\n    }\n}","typeGuard":"boolean isValidHttpPackageUrl(String url) {\n    try {\n        java.net.URL u = new java.net.URL(url);\n        return (u.getProtocol().equals(\"http\") || u.getProtocol().equals(\"https\")) && u.getHost() != null;\n    } catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n    functionActioner.startFunction(...);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Package URL\")) {\n        // re-upload package and fix metadata URL\n    } else { throw e; }\n}","preventionTips":["Validate http(s) URLs are well-formed and reachable before submitting functions","Prefer the Pulsar package management service over raw HTTP URLs","Keep URLs free of typos, unencoded spaces, and path traversal"],"tags":["pulsar-functions","worker","download","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"}