apache/pulsar · error · IllegalArgumentException

Cannnot get absolute path from specified URL

Error message

Cannnot get absolute path from specified URL

What it means

getAbsolutePathFromUrl wraps InstantiationException, IllegalAccessException, and IOException into IllegalArgumentException('Cannnot get absolute path from specified URL'). This fires when the URL is syntactically valid (unlike the URISyntaxException case) but the connection/open step fails — e.g. the file does not exist or cannot be opened.

Source

Thrown at pulsar-client-auth-athenz/src/main/java/org/apache/pulsar/client/impl/auth/AuthenticationAthenz.java:312

        return ztsClient;
    }

    private static void checkRequiredParams(Map<String, String> authParams, String... requiredParams) {
        for (String param : requiredParams) {
            checkArgument(isNotBlank(authParams.get(param)), "Missing required parameter: %s", param);
        }
    }

    private static String getAbsolutePathFromUrl(String urlString) {
        try {
            java.net.URL url = new URL(urlString).openConnection().getURL();
            checkArgument("file".equals(url.getProtocol()), "Unsupported protocol: %s", url.getProtocol());
            Path path = Paths.get(url.getPath());
            return path.isAbsolute() ? path.toString() : path.toAbsolutePath().toString();
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException("Invalid URL format", e);
        } catch (InstantiationException | IllegalAccessException | IOException e) {
            throw new IllegalArgumentException("Cannnot get absolute path from specified URL", e);
        }
    }

    private static PrivateKey loadPrivateKey(String privateKeyURL) {
        PrivateKey privateKey = null;
        try {
            URLConnection urlConnection = new URL(privateKeyURL).openConnection();
            String protocol = urlConnection.getURL().getProtocol();
            if ("data".equals(protocol) && !APPLICATION_X_PEM_FILE.equals(urlConnection.getContentType())) {
                throw new IllegalArgumentException(
                        "Unsupported media type or encoding format: " + urlConnection.getContentType());
            }
            String keyData = CharStreams.toString(new InputStreamReader((InputStream) urlConnection.getContent(),
                    Charset.defaultCharset()));
            privateKey = Crypto.loadPrivateKey(keyData);
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException("Invalid privateKey format", e);
        } catch (CryptoException | InstantiationException | IllegalAccessException | IOException e) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Confirm the file exists and is readable: ls -l /path/to/key.pem as the same user running Pulsar
  2. Use an absolute path (the method resolves relative paths, but the file must still exist)
  3. If the key is not on local disk, embed it directly with a data:application/x-pem-file URI in 'privateKey'

Example fix

// before
{"privateKeyPath":"file:///etc/pulsar/athenz_priv_key.pem"} // file does not exist
// after
$ ls /etc/pulsar/  # verify the file, fix the path
{"privateKeyPath":"file:///etc/pulsar/actual_key.pem"}
Defensive patterns

Strategy: validation

Validate before calling

String path = URI.create(keyUrl).getPath();
if (!Files.isRegularFile(Paths.get(path))) {
    throw new IllegalArgumentException("privateKeyPath target does not exist: " + path);
}
if (!Files.isReadable(Paths.get(path))) {
    throw new IllegalArgumentException("privateKeyPath not readable by this user: " + path);
}

Type guard

boolean isReadableFile(String fileUrl) {
    try { return Files.isReadable(Paths.get(URI.create(fileUrl).getPath())); }
    catch (Exception e) { return false; }
}

Try / catch

try {
    authentication.configure(authParamsJson);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Cannnot get absolute path")) {
        log.error("Key URL is valid but unreadable — check the file exists and permissions");
    }
    throw e;
}

Prevention

When it happens

Trigger: configure()/setAuthParams given a privateKeyPath file URL whose target file is missing, unreadable (permissions), or whose connection throws IOException during getAbsolutePathFromUrl.

Common situations: Wrong absolute path after moving config between hosts; the process user lacks read permission on the key file; relative path assumed to resolve to an existing file but file absent.

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/154b46e5d5927f68. Report an issue: GitHub.