apache/pulsar · error · IllegalArgumentException

This version of pulsar-client supports only file:// encrypti

Error message

This version of pulsar-client supports only file:// encryption keys; got '${fileUri}'.

What it means

fileUriToPath resolves the --decryption-key (or similar) argument, which must be a file:// URI, into a filesystem Path. This build of pulsar-client only supports reading encryption keys from local files, so any other URI scheme (http, s3, classpath, etc.) is rejected with IllegalArgumentException before any I/O is attempted.

Source

Thrown at pulsar-client-tools/src/main/java/org/apache/pulsar/client/cli/AbstractCmd.java:47

        return run();
    }

    abstract int run() throws Exception;

    /**
     * Resolve a {@code file:} URI (as accepted by the encryption-key flags) to a {@link Path}.
     * Supports both the hierarchical form ({@code file:///abs/path}, where {@link URI#getPath()}
     * is set) and the opaque relative form ({@code file:rel/path}, where the path lives in the
     * scheme-specific part).
     *
     * @param fileUri a {@code file:} URI string
     * @return the resolved {@link Path}
     * @throws IllegalArgumentException if the URI scheme is not {@code file}
     */
    static Path fileUriToPath(String fileUri) {
        URI uri = URI.create(fileUri);
        if (!"file".equalsIgnoreCase(uri.getScheme())) {
            throw new IllegalArgumentException("This version of pulsar-client supports only file:// "
                    + "encryption keys; got '" + fileUri + "'.");
        }
        String path = uri.getPath();
        if (path == null) {
            // Opaque (relative) file: URI, e.g. file:../certs/key.pem
            path = uri.getSchemeSpecificPart();
        }
        return Path.of(path);
    }
}

View on GitHub (pinned to 820761864e)

Solutions

  1. Copy the key to local disk and pass a proper file:// URI, e.g. file:///etc/pulsar/key.pem
  2. Check the URI scheme spelling and format (file:///abs/path); note opaque relative URIs like file:../certs/key.pem are handled via getSchemeSpecificPart
  3. If the key must come from remote storage, pre-download it in a wrapper script before invoking the CLI, or use a client version/build that supports that key provider

Example fix

// before
--decryption-key http://secrets.example.com/key.pem
// after
curl -o /tmp/key.pem http://secrets.example.com/key.pem
--decryption-key file:///tmp/key.pem
Defensive patterns

Strategy: validation

Validate before calling

URI uri = URI.create(keyUri);
if (!"file".equalsIgnoreCase(uri.getScheme()))
    throw new IllegalArgumentException("key must be a file:// URI: " + keyUri);

Type guard

static boolean isFileUri(String s) {
    try { return "file".equalsIgnoreCase(URI.create(s).getScheme()); }
    catch (Exception e) { return false; }
}

Try / catch

try {
    Path p = fileUriToPath(keyUri);
} catch (IllegalArgumentException e) {
    LOG.error("Only file:// encryption keys are supported: {}", e.getMessage());
    keyPath = downloadToLocalTemp(keyUri); // fallback
}

Prevention

When it happens

Trigger: Passing a key location with a scheme other than file to AbstractCmd.fileUriToPath, e.g. -dk http://host/key.pem, s3://bucket/key.pem, or an opaque URI whose scheme is not 'file'.

Common situations: Pointing the CLI at a key hosted on an HTTP server or object store because that is where secrets live; copying a config from a newer/other client that supports remote keys; typo like files:// or file:/path written without the scheme.

Related errors


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