{"record":{"id":"078f30f3ab39c142","repo":"apache/pulsar","slug":"failed-to-parse-tlsfactoryconfig-as-a-json-object","errorCode":null,"errorMessage":"Failed to parse tlsFactoryConfig as a JSON object","messagePattern":"Failed to parse tlsFactoryConfig as a JSON object","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-broker-common/src/main/java/org/apache/pulsar/broker/tls/TlsFactorySupport.java","lineNumber":196,"sourceCode":"     * map; a value starting with <code>{</code> is parsed as a JSON object; otherwise it is parsed as a\n     * comma-separated {@code key=value} list.\n     *\n     * @param tlsFactoryConfig the configured factory params (may be null/blank)\n     * @return an immutable params map (possibly empty)\n     */\n    public static Map<String, String> parseFactoryConfig(String tlsFactoryConfig) {\n        if (StringUtils.isBlank(tlsFactoryConfig)) {\n            return Map.of();\n        }\n        String trimmed = tlsFactoryConfig.trim();\n        if (trimmed.startsWith(\"{\")) {\n            try {\n                Map<String, String> parsed = ObjectMapperFactory.getMapper().reader()\n                        .forType(new TypeReference<Map<String, String>>() {})\n                        .readValue(trimmed);\n                return parsed == null ? Map.of() : Map.copyOf(parsed);\n            } catch (Exception e) {\n                throw new IllegalArgumentException(\"Failed to parse tlsFactoryConfig as a JSON object\", e);\n            }\n        }\n        Map<String, String> map = new LinkedHashMap<>();\n        for (String pair : trimmed.split(\",\")) {\n            String entry = pair.trim();\n            if (entry.isEmpty()) {\n                continue;\n            }\n            int eq = entry.indexOf('=');\n            if (eq < 0) {\n                map.put(entry, \"\");\n            } else {\n                map.put(entry.substring(0, eq).trim(), entry.substring(eq + 1).trim());\n            }\n        }\n        return Map.copyOf(map);\n    }\n","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/tls/TlsFactorySupport.java#L178-L214","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (broker.conf)\ntlsFactoryConfig={'key':'value',}\n// after\ntlsFactoryConfig={\"key\":\"value\"}","handlingStrategy":"validation","validationCode":"String cfg = conf.getTlsFactoryConfig();\nif (cfg != null && cfg.trim().startsWith(\"{\")) {\n    try {\n        new ObjectMapper().readValue(cfg, new TypeReference<Map<String, String>>() {});\n    } catch (Exception e) {\n        throw new IllegalArgumentException(\"tlsFactoryConfig is not a valid JSON string map\", e);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["configuration","tls","json","broker"],"backgroundTag":"config-json-parse-error","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}