apache/pulsar · error · IllegalArgumentException

Invalid privateKey format

Error message

Invalid privateKey format

What it means

loadPrivateKey reads the key data from the URL and parses it with Crypto.loadPrivateKey. A URISyntaxException is rethrown as IllegalArgumentException('Invalid privateKey format'); a CryptoException or IOException results in null being returned (which surfaces as error 'Failed to load private key...' from setAuthParams). So this specific message means the privateKey URL string itself is malformed.

Source

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

        } 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) {
            privateKey = null;
        }
        return privateKey;
    }
}

View on GitHub (pinned to 820761864e)

Solutions

  1. Prefix PEM content correctly: 'data:application/x-pem-file,<pem>' or base64-encode it with the same media type
  2. Alternatively use 'privateKeyPath' with a well-formed file:/// URL
  3. Remove/escape newlines and whitespace from the URI value

Example fix

// before
"privateKey":"-----BEGIN PRIVATE KEY-----\nMIIEv...\n-----END PRIVATE KEY-----"
// after
"privateKey":"data:application/x-pem-file,-----BEGIN PRIVATE KEY-----\\nMIIEv...\\n-----END PRIVATE KEY-----"
Defensive patterns

Strategy: validation

Validate before calling

String pk = params.get("privateKey");
if (pk != null && !pk.startsWith("data:") && !pk.contains("://")) {
    throw new IllegalArgumentException("privateKey must be a data: URI or URL, not raw PEM text");
}
try { new URI(pk); } catch (URISyntaxException e) {
    throw new IllegalArgumentException("privateKey is not a valid URI (strip newlines, add data: prefix)", e);
}

Type guard

boolean isUriLike(String s) {
    return s != null && (s.startsWith("data:") || s.startsWith("file:") || s.contains("://"));
}

Try / catch

try {
    authentication.configure(authParamsJson);
} catch (IllegalArgumentException e) {
    if (e.getMessage().equals("Invalid privateKey format")) {
        log.error("privateKey must be a valid URI — wrap PEM in data:application/x-pem-file,... or use privateKeyPath");
    }
    throw e;
}

Prevention

When it happens

Trigger: configure() called with a 'privateKey' value that is neither a valid URL nor valid data URI — e.g. raw PEM text without the 'data:' prefix, or a truncated/typo'd URI scheme.

Common situations: Pasting the multi-line PEM body directly as privateKey (newlines break the URI parser); forgetting the data:application/x-pem-file prefix; typos like 'data::...' or 'file//...'.

Related errors


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