prestodb/presto · error · PrestoException
NATIVEPLANCHECKER_UNKNOWN_CONVERSION_FAILURE
NATIVEPLANCHECKER_UNKNOWN_CONVERSION_FAILURE
Error message
Error response without failure from native plan checker with code: {statusCode} What it means
When the plan checker returns a non-200 response, NativePlanChecker.processResponseFailure expects the body to decode into a PlanConversionResponse containing failure info. If the body is null or empty, there is nothing to convert, so it throws NATIVEPLANCHECKER_UNKNOWN_CONVERSION_FAILURE with the HTTP status code — the real failure reason is unknown.
Source
Thrown at presto-native-sidecar-plugin/src/main/java/com/facebook/presto/sidecar/nativechecker/NativePlanChecker.java:231
.setHeader(CONTENT_TYPE, JSON_UTF_8.toString())
.setBodyGenerator(createStaticBodyGenerator(requestBodyJson, UTF_8))
.build();
}
private URI getSidecarLocation()
{
Node sidecarNode = nodeManager.getSidecarNode();
return HttpUriBuilder
.uriBuilderFrom(sidecarNode.getHttpUri())
.appendPath(PLAN_CONVERSION_ENDPOINT)
.build();
}
private NativeSidecarFailureInfo processResponseFailure(StringResponse response)
{
String responseBody = response.getBody();
if (responseBody == null || responseBody.isEmpty()) {
throw new PrestoException(NATIVEPLANCHECKER_UNKNOWN_CONVERSION_FAILURE, "Error response without failure from native plan checker with code: " + response.getStatusCode());
}
PlanConversionResponse planConversionResponse = PLAN_CONVERSION_RESPONSE_JSON_CODEC.fromJson(responseBody);
if (planConversionResponse.getFailures().isEmpty()) {
throw new PrestoException(NATIVEPLANCHECKER_UNKNOWN_CONVERSION_FAILURE, "Error response without failure from native plan checker with code: " + response.getStatusCode());
}
return planConversionResponse.getFailures().get(0);
}
private static class CheckInternalVisitor
extends PlanVisitor<Boolean, Void>
{
@Override
public Boolean visitTableScan(TableScanNode tableScan, Void context)
{
TableHandle handle = tableScan.getTable();
return ConnectorId.isInternalSystemConnector(handle.getConnectorId());View on GitHub (pinned to 55bb57d202)
Solutions
- Check the HTTP status code in the message and the sidecar/proxy logs for that request.
- If a proxy returns empty 502/504, fix connectivity/timeouts between coordinator and sidecar.
- Check sidecar container logs for a crash (OOM) during plan conversion.
- Retry the query once sidecar is healthy; ensure sidecar returns structured failure JSON on errors.
Defensive patterns
Strategy: retry
Validate before calling
// require structured errors from the checker service assertSidecarReturnsJsonErrors(); // verify sidecar never returns bare/empty error bodies
Type guard
boolean hasFailureBody(StringResponse r) { return r.getBody() != null && !r.getBody().isEmpty(); } Try / catch
try { validateFragment(fragment); }
catch (PrestoException e) {
if ("NATIVEPLANCHECKER_UNKNOWN_CONVERSION_FAILURE".equals(e.getErrorCode().getName())) {
log.warn("Empty checker error body; checking sidecar/proxy health then retrying");
if (sidecarHealthy()) retryOnce(); else failFast(e);
} else throw e;
} Prevention
- Bypass or correctly configure proxies between coordinator and sidecar
- Ensure sidecar serializes failure JSON for all error paths
- Monitor for sidecar OOM/crash loops
- Check the status code in the message to distinguish 5xx vs gateway errors
When it happens
Trigger: validateFragment -> runValidation gets a non-200 response whose body is null or empty; processResponseFailure hits the first guard.
Common situations: Sidecar crashing mid-request (empty 500 body); proxy/load balancer intercepting and returning bare status codes (502/504 with empty body); request timeout at the gateway.
Related errors
- Error from native plan checker: %s
- NATIVEPLANCHECKER_CONNECTION_ERROR
- NO_CPP_SIDECARS
- NOT_SUPPORTED
- INVALID_ARGUMENTS
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/d541dd6b484d533a.
Report an issue: GitHub.