apache/pulsar · error · IllegalArgumentException
Failed to parse tlsFactoryConfig as a JSON object
Error message
Failed to parse tlsFactoryConfig as a JSON object
What it means
IllegalArgumentException thrown by TlsFactorySupport.parseFactoryConfig when the tlsFactoryConfig value cannot be parsed as a JSON object of Map<String,String>. The method first tries a full JSON parse via ObjectMapperFactory; any exception (malformed JSON, wrong JSON shape, non-string values) is wrapped with this message. tlsFactoryConfig is expected to be either a JSON object like {"key":"value"} or a comma-separated key=value list.
Source
Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/broker/tls/TlsFactorySupport.java:196
* map; a value starting with <code>{</code> is parsed as a JSON object; otherwise it is parsed as a
* comma-separated {@code key=value} list.
*
* @param tlsFactoryConfig the configured factory params (may be null/blank)
* @return an immutable params map (possibly empty)
*/
public static Map<String, String> parseFactoryConfig(String tlsFactoryConfig) {
if (StringUtils.isBlank(tlsFactoryConfig)) {
return Map.of();
}
String trimmed = tlsFactoryConfig.trim();
if (trimmed.startsWith("{")) {
try {
Map<String, String> parsed = ObjectMapperFactory.getMapper().reader()
.forType(new TypeReference<Map<String, String>>() {})
.readValue(trimmed);
return parsed == null ? Map.of() : Map.copyOf(parsed);
} catch (Exception e) {
throw new IllegalArgumentException("Failed to parse tlsFactoryConfig as a JSON object", e);
}
}
Map<String, String> map = new LinkedHashMap<>();
for (String pair : trimmed.split(",")) {
String entry = pair.trim();
if (entry.isEmpty()) {
continue;
}
int eq = entry.indexOf('=');
if (eq < 0) {
map.put(entry, "");
} else {
map.put(entry.substring(0, eq).trim(), entry.substring(eq + 1).trim());
}
}
return Map.copyOf(map);
}
View on GitHub (pinned to 820761864e)
Solutions
- Rewrite tlsFactoryConfig as valid JSON with double quotes: {"provider":"jdk"}
- Ensure every JSON value is a string (quote numbers and booleans)
- Validate the JSON with a linter (jq) before deploying
- Alternatively use the simple comma-separated key=value form (k1=v1,k2=v2) which the parser falls back to
Example fix
// before (broker.conf)
tlsFactoryConfig={'key':'value',}
// after
tlsFactoryConfig={"key":"value"} Defensive patterns
Strategy: validation
Validate before calling
String cfg = conf.getTlsFactoryConfig();
if (cfg != null && cfg.trim().startsWith("{")) {
try {
new ObjectMapper().readValue(cfg, new TypeReference<Map<String, String>>() {});
} catch (Exception e) {
throw new IllegalArgumentException("tlsFactoryConfig is not a valid JSON string map", e);
}
} Prevention
- Keep tlsFactoryConfig as valid JSON with double quotes and string values only
- Run jq (or similar) over JSON config values before deploy
- Prefer the k1=v1,k2=v2 form when JSON quoting is fragile in your config pipeline
- Add a startup config-validation step in CI
When it happens
Trigger: Setting broker/service tlsFactoryConfig to malformed JSON (e.g. {'key':'value'} with single quotes, trailing commas, unquoted keys) so readValue() throws; also thrown upstream if a non-string JSON value (number/bool/nested object) makes the TypeReference<Map<String,String>> binding fail.
Common situations: Config copied from docs with single quotes instead of double quotes; shell or YAML config stripping double quotes; users supplying key=value pairs with stray characters that also fail the fallback comma parser; upgrading and migrating a config that previously used a different format.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- webServicePort/webServicePortTls or http/https bindAddresses
- The retention size must > the backlog quota limit size, but
- The retention time must > the backlog quota limit time, but
- brokerDeleteInactiveTopicsEnabled and brokerCloseInactiveTop
- brokerCloseInactiveTopicsEnabled only supports brokerDeleteI
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/078f30f3ab39c142.
Report an issue: GitHub.