prestodb/presto · error · PrestoException

PLAN_SERIALIZATION_ERROR

PLAN_SERIALIZATION_ERROR

Error message

Cannot serialize plan to JSON

What it means

CanonicalPlan.toString(ObjectMapper) serializes the canonical plan to JSON for logging/transport. If Jackson raises a JsonProcessingException (non-serializable field, invalid state, missing serializer), Presto wraps it in PLAN_SERIALIZATION_ERROR. This indicates the canonical plan contains something the configured ObjectMapper cannot represent.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/planner/CanonicalPlan.java:91

        return Objects.hash(plan, strategy);
    }

    @Override
    public String toString()
    {
        return toStringHelper(this)
                .add("plan", plan)
                .add("strategy", strategy)
                .toString();
    }

    public String toString(ObjectMapper objectMapper)
    {
        try {
            return objectMapper.writeValueAsString(this);
        }
        catch (JsonProcessingException e) {
            throw new PrestoException(PLAN_SERIALIZATION_ERROR, "Cannot serialize plan to JSON", e);
        }
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Ensure the ObjectMapper used has all required Jackson modules registered (e.g. Presto's json codecs for handles, types, plan nodes)
  2. Find and fix the offending field in the canonical plan (see the cause JsonProcessingException in the stack trace)
  3. Report/upgrade if triggered by core Presto plan nodes after a version upgrade

Example fix

// before
ObjectMapper plainMapper = new ObjectMapper();
String json = canonicalPlan.toString(plainMapper);
// after
ObjectMapper mapper = jsonMapperFactory(); // includes Presto modules
mapper.registerModule(new SimpleModule().addSerializer(MyHandle.class, new MyHandleSerializer()));
String json = canonicalPlan.toString(mapper);
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: ensure the mapper can serialize before asking the plan to
try { mapper.writeValueAsString(planProbeFields); } catch (JsonProcessingException e) { /* register missing modules first */ }

Try / catch

try { String json = canonicalPlan.toString(mapper); } catch (PrestoException e) { if (e.getErrorCode().equals(PLAN_SERIALIZATION_ERROR.toErrorCode())) { registerMissingJacksonModules(mapper); retry(); } else throw e; }

Prevention

When it happens

Trigger: Calling toString(objectMapper) on a CanonicalPlan whose members include types lacking Jackson serializers (custom handles, lambdas, unregistered types) or a broken module registration in the ObjectMapper.

Common situations: Custom connectors/plugins adding plan metadata not covered by Jackson modules; version upgrades changing serialization annotations; constructing CanonicalPlan with a CanonicalTableHandle referencing a non-serializable connector object.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/a9a8a59c8d745e20. Report an issue: GitHub.