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
parseFactoryConfig parses the tlsFactoryConfig string, accepting either a JSON object mapping strings to strings or a comma-separated key=value list. If the string looks like JSON but cannot be parsed into Map<String,String>, an IllegalArgumentException is thrown. The config string is therefore malformed.
Source
Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/tls/ClientTlsFactorySupport.java:367
* <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)
*/
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
- Provide valid JSON: {"key1":"value1","key2":"value2"} with quoted keys and values.
- Or use the simple comma form: key1=value1,key2=value2.
- Validate the string with a JSON linter / JSON.parse before putting it in config.
- Check shell/env quoting so double quotes are not stripped before the client sees the value.
Example fix
// before
String config = "{keyA: valueA}"; // invalid JSON
// after
String config = "{\"keyA\":\"valueA\"}"; // or "keyA=valueA" Defensive patterns
Strategy: validation
Validate before calling
String trimmed = tlsFactoryConfig.trim();
if (trimmed.startsWith("{")) {
try { new ObjectMapper().readValue(trimmed, new TypeReference<Map<String,String>>() {}); }
catch (Exception e) { throw new IllegalArgumentException("tlsFactoryConfig is not valid JSON", e); }
} Try / catch
try {
applyTlsFactoryConfig(raw);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Failed to parse tlsFactoryConfig")) {
log.error("Use {\"k\":\"v\"} JSON or k=v,k2=v2 form", e);
}
} Prevention
- Prefer the simple k=v,k2=v2 form over JSON to avoid quoting pitfalls
- Validate the config string with a JSON parser in tests
- Mind shell/env quoting: double quotes may be stripped
- Keep keys and values JSON-quoted if using JSON
When it happens
Trigger: Setting tlsFactoryConfig to invalid JSON such as "{key: value}" (unquoted keys), "{..." truncated JSON, or a value that is neither valid JSON nor a clean key=value list.
Common situations: Hand-editing the config with unquoted JSON keys; YAML/shell quoting stripping double quotes so only braces remain; mixing JSON and comma-list syntax; trailing commas.
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
- Failed to parse tlsFactoryConfig as a JSON object
- Could not instantiate <configKeyName> '<factoryClassName>'
- Client TLS configuration is invalid for purpose <purpose>: <
- Failed to parse SASL authParams
- Malformed configuration file
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/af0f433bc74efe62.
Report an issue: GitHub.