apache/pulsar · error · IOException
Invalid privateKey format
Error message
Invalid privateKey format
What it means
loadPrivateKey() wraps URISyntaxException, InstantiationException and IllegalAccessException into IOException('Invalid privateKey format'). This means the privateKey value could not be interpreted as a valid URL at all — typically a malformed URI syntax in the privateKey parameter (not the JSON payload itself, which is handled elsewhere).
Source
Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/oauth2/ClientCredentialsFlow.java:146
URLConnection urlConnection = new org.apache.pulsar.client.api.url.URL(privateKeyURL).openConnection();
try {
String protocol = urlConnection.getURL().getProtocol();
String contentType = urlConnection.getContentType();
if ("data".equals(protocol) && !"application/json".equals(contentType)) {
throw new IllegalArgumentException(
"Unsupported media type or encoding format: " + urlConnection.getContentType());
}
KeyFile privateKey;
try (Reader r = new InputStreamReader((InputStream) urlConnection.getContent(),
StandardCharsets.UTF_8)) {
privateKey = KeyFile.fromJson(r);
}
return privateKey;
} finally {
IOUtils.close(urlConnection);
}
} catch (URISyntaxException | InstantiationException | IllegalAccessException e) {
throw new IOException("Invalid privateKey format", e);
}
}
@Override
public void initialize() throws PulsarClientException {
super.initialize();
assert this.metadata != null;
URL tokenUrl = this.metadata.getTokenEndpoint();
this.exchanger = new TokenClient(tokenUrl, getHttpClient());
initialized = true;
}
public TokenResult authenticate() throws PulsarClientException {
// read the private key from storage
KeyFile keyFile;
try {
keyFile = loadPrivateKey(this.privateKey);View on GitHub (pinned to 820761864e)
Solutions
- URL-encode special characters in the privateKey value (spaces as %20)
- Prefix local paths with file: and ensure valid URI syntax
- Log/print the privateKey value (careful with secrets) and test it with new URI(value) first
Example fix
// before String key = "/etc/pulsar/oauth2/my key.json"; // after String key = "file:/etc/pulsar/oauth2/my%20key.json";
Defensive patterns
Strategy: validation
Validate before calling
String key = authParams.get("privateKey");
try {
new java.net.URI(key);
} catch (java.net.URISyntaxException e) {
throw new IllegalArgumentException("privateKey is not a valid URI: " + e.getMessage());
} Type guard
boolean isValidKeyUri(String v) {
if (v == null || v.isBlank()) return false;
try { new java.net.URI(v); return true; } catch (java.net.URISyntaxException e) { return false; }
} Try / catch
try {
flow.initialize();
} catch (PulsarClientException.AuthenticationException e) {
if (e.getMessage().contains("Invalid privateKey format")) {
throw new ConfigException("privateKey must be a well-formed URI (URL-encode spaces/special chars)", e);
}
throw e;
} Prevention
- URL-encode paths containing spaces or special characters
- Prefix local file paths with file: scheme
- Validate the privateKey URI with new URI(value) before configuring the client
When it happens
Trigger: privateKey string containing spaces, unencoded special characters, or an invalid scheme so new URL(privateKeyURL) throws URISyntaxException; file paths with illegal characters; a value like 'file:/path with spaces/key.json'.
Common situations: Paste errors adding whitespace/newlines to the privateKey config; paths with non-URL-safe characters; using a plain path string instead of a proper file: URL.
Related errors
- Malformed configuration parameter: earlyTokenRefreshPercent
- Unsupported media type or encoding format: ${contentType}
- Unable to read private key: ${message}
- Required configuration parameter: ${name}
- Malformed configuration parameter: ${name}
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/350195a82c6fa33e.
Report an issue: GitHub.