apache/pulsar · error · ParseEnsemblePlacementPolicyConfigException

Failed to encode to json

Error message

Failed to encode to json

What it means

EnsemblePlacementPolicyConfig.encode serializes the policy config object to pretty-printed JSON with Jackson. If Jackson raises a JsonProcessingException (unserializable property, invalid accessor, recursion), the original exception is wrapped in ParseEnsemblePlacementPolicyConfigException('Failed to encode to json'). For this simple POJO it is rare and usually indicates a bad getter or an incompatible Jackson version on the classpath.

Source

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

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof EnsemblePlacementPolicyConfig) {
            EnsemblePlacementPolicyConfig other = (EnsemblePlacementPolicyConfig) obj;
            return Objects.equals(this.policyClass == null ? null : this.policyClass.getName(),
                other.policyClass == null ? null : other.policyClass.getName())
                && Objects.equals(this.properties, other.properties);
        }
        return false;
    }

    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) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Read the wrapped cause (e.getCause()) of ParseEnsemblePlacementPolicyConfigException — it names the exact property/serialization problem.
  2. Fix or annotate the offending field (e.g. @JsonIgnore on transient/getter-throwing properties).
  3. Check the classpath for duplicated or shaded Jackson databind versions and align them to the Pulsar-provided version.
  4. If a custom placement policy object is embedded, ensure it is JSON-serializable or store only its class name + serializable metadata map.

Example fix

// before
class MyPolicyConfig { InputStream stream; } // unserializable
// after
class MyPolicyConfig {
    @com.fasterxml.jackson.annotation.JsonIgnore
    private InputStream stream;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// sanity-check serializability before encode
new ObjectMapper().writeValueAsString(config); // throws JsonProcessingException early if unserializable

Try / catch

try {
    byte[] json = config.encode();
} catch (EnsemblePlacementPolicyConfig.ParseEnsemblePlacementPolicyConfigException e) {
    log.error("JSON encode failed for placement policy config", e.getCause());
    throw e;
}

Prevention

When it happens

Trigger: Calling encode() (directly or via buildMetadataForPlacementPolicyConfig) when the config object contains a property Jackson cannot serialize — e.g. a custom policy-class field with a getter throwing, an exotic type without a serializer, or a shaded/duplicate Jackson version conflict.

Common situations: Custom BookKeeper ensemble placement policy classes bundled with dependencies that shade an incompatible Jackson; adding non-POJO fields to a subclassed config; OSGi/classloader conflicts in function workers.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


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