apache/pulsar · error · ParseEnsemblePlacementPolicyConfigException

Failed to decode from json

Error message

Failed to decode from json

What it means

EnsemblePlacementPolicyConfig.decode parses a JSON byte array back into an EnsemblePlacementPolicyConfig via a static Jackson ObjectReader. Any IOException from Jackson — malformed JSON, wrong structure, unknown-type mismatch, or truncated data — is wrapped as ParseEnsemblePlacementPolicyConfigException('Failed to decode from json').

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/policies/data/EnsemblePlacementPolicyConfig.java:89

    public byte[] encode() throws ParseEnsemblePlacementPolicyConfigException {
        try {
            return ObjectMapperFactory.getMapper()
                .writer().withDefaultPrettyPrinter()
                .writeValueAsString(this)
                .getBytes(StandardCharsets.UTF_8);
        } catch (JsonProcessingException e) {
            throw new ParseEnsemblePlacementPolicyConfigException("Failed to encode to json", e);
        }
    }

    private static final ObjectReader ENSEMBLE_PLACEMENT_CONFIG_READER = ObjectMapperFactory.getMapper()
            .reader().forType(EnsemblePlacementPolicyConfig.class);

    public static EnsemblePlacementPolicyConfig decode(byte[] data) throws ParseEnsemblePlacementPolicyConfigException {
        try {
            return ENSEMBLE_PLACEMENT_CONFIG_READER.readValue(data);
        } catch (IOException e) {
            throw new ParseEnsemblePlacementPolicyConfigException("Failed to decode from json", e);
        }
    }

    public static class ParseEnsemblePlacementPolicyConfigException extends Exception {
        private static final long serialVersionUID = 1L;

        ParseEnsemblePlacementPolicyConfigException(String message, Throwable throwable) {
            super(message, throwable);
        }
    }
}

View on GitHub (pinned to 820761864e)

Solutions

  1. Inspect the wrapped cause — Jackson messages name the offending field/line in the JSON.
  2. Validate/pretty-print the source JSON and correct syntax or field types to match EnsemblePlacementPolicyConfig.
  3. If produced by an older Pulsar version, upgrade the client/cluster or re-create the namespace isolation policy via the admin API (pulsar-admin namespaces set-namespace-isolation-policy).
  4. Delete and re-create the corrupt policy metadata rather than hand-patching it.

Example fix

// before
byte[] bad = "{policy: ...".getBytes(); // malformed
cfg = EnsemblePlacementPolicyConfig.decode(bad);
// after
byte[] good = "{\"policyClass\":\"org.apache.pulsar...\",\"autoFailoverPolicy\":{...}}".getBytes();
cfg = EnsemblePlacementPolicyConfig.decode(good); // valid JSON matching the type
Defensive patterns

Strategy: try-catch

Validate before calling

// validate JSON parses before decode
static boolean isJson(byte[] data) {
    try { new ObjectMapper().readTree(data); return true; }
    catch (IOException e) { return false; }
}

Try / catch

try {
    EnsemblePlacementPolicyConfig cfg = EnsemblePlacementPolicyConfig.decode(data);
} catch (EnsemblePlacementPolicyConfig.ParseEnsemblePlacementPolicyConfigException e) {
    log.error("Failed to decode placement policy config", e.getCause());
    // fall back to defaults or re-create the policy via the admin API
}

Prevention

When it happens

Trigger: Calling decode(bytes) with bytes that are not valid JSON for this type: corrupt znode/metadata content, JSON produced by a different schema/version, empty or truncated byte arrays, or hand-written JSON with wrong types (e.g. string where a map is expected).

Common situations: Reading policy metadata stored by an older/newer Pulsar version with an incompatible layout; manual edits to namespace-isolation policy data in ZooKeeper/metadata store; passing the wrong byte payload (e.g. another config's JSON) into decode.

Understand the failure class

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/8e9f002b6503ddb1. Report an issue: GitHub.