apache/pulsar · error · IllegalArgumentException
Invalid MetadataStoreConfig query parameter '${param}'. Expe
Error message
Invalid MetadataStoreConfig query parameter '${param}'. Expected key=value What it means
MetadataStoreUrl.parse() splits the metadata store URL into provider params and MetadataStoreConfig params. A query param whose key is a known config key but lacks a '=' separator (i.e., a bare flag like ?sessionTimeoutMillis) cannot be applied and throws IllegalArgumentException 'Expected key=value'.
Source
Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/MetadataStoreUrl.java:55
String query = metadataStoreUrl.substring(queryStart + 1);
if (query.isEmpty()) {
return new MetadataStoreUrl(url, Map.of());
}
Map<String, String> configParams = new LinkedHashMap<>();
List<String> providerParams = new ArrayList<>();
for (String param : query.split("&", -1)) {
if (param.isEmpty()) {
continue;
}
int separator = param.indexOf('=');
String key = decodeQueryParam(separator > 0 ? param.substring(0, separator) : param);
if (!MetadataStoreConfigQueryParams.contains(key)) {
providerParams.add(param);
continue;
}
if (separator <= 0) {
throw new IllegalArgumentException("Invalid MetadataStoreConfig query parameter '" + param
+ "'. Expected key=value");
}
String value = decodeQueryParam(param.substring(separator + 1));
configParams.put(key, value);
}
if (!providerParams.isEmpty()) {
url += "?" + String.join("&", providerParams);
}
return new MetadataStoreUrl(url, Map.copyOf(configParams));
}
private static String removeMetadataStoreScheme(String metadataServiceUri) {
String prefix = AbstractMetadataDriver.METADATA_STORE_SCHEME + ":";
if (metadataServiceUri.startsWith(prefix)) {
return metadataServiceUri.substring(prefix.length());
}View on GitHub (pinned to 820761864e)
Solutions
- Append '=value' to the parameter (e.g. sessionTimeoutMillis=30000) or remove the bare key entirely.
- Check the full URL wasn't truncated by config tooling or shell escaping.
- Verify the param belongs in the config section vs provider params — unknown keys are routed to providerParams and won't trigger this.
Example fix
// before zk://zk1:2181/ledgers?sessionTimeoutMillis // after zk://zk1:2181/ledgers?sessionTimeoutMillis=30000
Defensive patterns
Strategy: validation
Validate before calling
for (String param : query.split("&")) {
int sep = param.indexOf('=');
if (sep <= 0 && MetadataStoreConfigQueryParams.contains(decode(param)))
throw new IllegalArgumentException("param needs key=value: " + param);
} Prevention
- Always write query params as key=value
- Check URLs aren't truncated by templating/shell escaping
- Remove bare keys with no value
When it happens
Trigger: A known config key appearing in the query string without '=value', e.g. metadata-store-url: zk://host:2181/ledgers?sessionTimeoutMillis — from truncation, typos, or hand-editing URLs.
Common situations: Truncated URLs in configs; removing the value but leaving the key and '?key'; mistakes when converting provider-specific params into config params.
Related errors
- Metadata store address argument is required (--metadata-stor
- is not an instance of MetadataStore
- Neither METADATA_STORE_INSTANCE configuration set in the BK
- Unsupported MetadataStoreConfig query parameter '${key}'. Su
- MetadataStoreConfig query parameter '${key}' must be true or
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/0c00f2650295b2ac.
Report an issue: GitHub.