apache/pulsar · error · IOException

does not exists locally

Error message

 does not exists locally

What it means

FunctionCommon.extractFileFromPkgURL resolves a function/sink/source package URL to a local File. When the URL uses the file:// protocol but the referenced file cannot be found on the local filesystem, it throws this IOException (message: '<url> does not exists locally').

Solutions

  1. Verify the file exists at the exact path on the host resolving the URL and correct the path
  2. Copy the artifact to a location shared/visible to all function workers (e.g. a distributed filesystem mount or the same path on every node)
  3. Switch to an http(s):// package URL served from a reachable location, or upload the package to Pulsar's package management service
  4. Re-upload the artifact if it was deleted or a build cleanup removed it

Example fix

// before
new CreateFunction().setPkgUrl("file:///build/old/app.jar") // deleted by clean
// after
new CreateFunction().setPkgUrl("file:///opt/functions/app.jar"); // artifact placed on worker-visible path
// or: setPkgUrl("https://artifacts.internal/functions/app.jar")
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check the file:// package URL
String pkgUrl = "file:///opt/functions/app.jar";
if (pkgUrl.startsWith("file://")) {
  java.io.File f = new java.io.File(java.net.URI.create(pkgUrl));
  if (!f.exists() || !f.canRead()) {
    throw new IllegalStateException("Package not accessible on this host: " + pkgUrl);
  }
}

Try / catch

try {
  File f = FunctionCommon.extractFileFromPkgURL(pkgUrl);
} catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().endsWith("does not exists locally")) {
    log.error("Package file missing on worker host: {}", pkgUrl);
    // re-upload artifact or switch to an http(s) URL and retry
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Submitting/updating a function with a package URL like file:///path/to/app.jar where the path does not exist on the machine performing the resolution (function worker host), e.g. after the artifact was moved/deleted, a wrong absolute path, or submitting from a machine where the file exists but the worker's host where it does not.

Common situations: Cluster deployments where workers run on different nodes than the submitter; artifacts cleaned from /tmp or a shared mount that is not mounted; Docker containers lacking the volume containing the jar; typos in the file:// path.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionCommon.java:259

        try (InputStream in = connection.getInputStream()) {
            log.info().attr("url", destPkgUrl).attr("target", targetFile.getAbsoluteFile())
                    .log("Downloading function package");
            Files.copy(in, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
        }
        log.info().attr("url", destPkgUrl).attr("target", targetFile.getAbsoluteFile())
                .log("Downloading function package completed");
    }

    public static File createPkgTempFile() throws IOException {
        return File.createTempFile("functions", ".tmp");
    }

    public static File extractFileFromPkgURL(String destPkgUrl) throws IOException, URISyntaxException {
        if (destPkgUrl.startsWith(Utils.FILE)) {
            URL url = new URL(destPkgUrl);
            File file = new File(url.toURI());
            if (!file.exists()) {
                throw new IOException(destPkgUrl + " does not exists locally");
            }
            return file;
        } else if (destPkgUrl.startsWith("http")) {
            File tempFile = createPkgTempFile();
            tempFile.deleteOnExit();
            downloadFromHttpUrl(destPkgUrl, tempFile);
            return tempFile;
        } else {
            throw new IllegalArgumentException("Unsupported url protocol "
                    + destPkgUrl + ", supported url protocols: [file/http/https]");
        }
    }

    public static String getFullyQualifiedInstanceId(Instance instance) {
        return getFullyQualifiedInstanceId(
                instance.getFunctionMetaData().getFunctionDetails().getTenant(),
                instance.getFunctionMetaData().getFunctionDetails().getNamespace(),
                instance.getFunctionMetaData().getFunctionDetails().getName(),

View on GitHub (pinned to 820761864e)