prestodb/presto · error · RuntimeException

Unable to restore snapshot "${snapshotJson}".

Error message

Unable to restore snapshot "${snapshotJson}".

What it means

DdlVerification, in snapshot mode, reads a previously stored snapshot JSON string and deserializes it back into the control checksum via objectMapper.readValue(snapshotJson, String.class). If the stored snapshot is not valid JSON (or not a JSON string), it throws this RuntimeException, causing the DDL verification to fail rather than proceed with a corrupt checksum.

Source

Thrown at presto-verifier/src/main/java/com/facebook/presto/verifier/framework/DdlVerification.java:116

                    snapshotQueryConsumer.accept(new SnapshotQuery(getSourceQuery().getSuite(), getSourceQuery().getName(), isExplain, snapshot));
                    return new DdlMatchResult(MATCH, Optional.empty(), "", "");
                }
                catch (JsonProcessingException exception) {
                    throw new RuntimeException("Unable to save snapshot \"" + controlChecksum + "\".");
                }
            }
        }
        else if (QUERY_BANK_MODE.equals(runningMode)) {
            String key = format(VERIFIER_SNAPSHOT_KEY_PATTERN, getSourceQuery().getSuite(), getSourceQuery().getName(), isExplain);
            SnapshotQuery snapshotQuery = snapshotQueries.get(key);
            if (snapshotQuery != null) {
                ObjectMapper objectMapper = new ObjectMapper();
                String snapshotJson = snapshotQuery.getSnapshot();
                try {
                    controlChecksum = objectMapper.readValue(snapshotJson, String.class);
                }
                catch (JsonProcessingException exception) {
                    throw new RuntimeException("Unable to restore snapshot \"" + snapshotJson + "\".");
                }
            }
            else {
                return new DdlMatchResult(SNAPSHOT_DOES_NOT_EXIST, Optional.empty(), "", "");
            }
        }

        Statement testChecksumQuery = getChecksumQuery(test);
        testChecksumQueryContext.setChecksumQuery(formatSql(testChecksumQuery));
        String testChecksum = getOnlyElement(callAndConsume(
                () -> getHelperAction().execute(testChecksumQuery, TEST_CHECKSUM, checksumConverter),
                stats -> stats.getQueryStats().map(QueryStats::getQueryId).ifPresent(testChecksumQueryContext::setChecksumQueryId)).getResults());

        S controlObject;
        S testObject;

        try {
            controlObject = (S) sqlParser.createStatement(controlChecksum, PARSING_OPTIONS);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Inspect the snapshot JSON named in the message; validate it is a proper JSON string literal.
  2. Delete/re-save the corrupted snapshot entry in the query bank store and re-run the verification in setup mode to regenerate it.
  3. Use the same verifier version for snapshot setup and verification runs.
  4. Check the store column width/charset so the JSON is not truncated on save.

Example fix

// before
throw new RuntimeException("Unable to restore snapshot \"" + snapshotJson + "\".");
// after
throw new RuntimeException("Unable to restore snapshot \"" + snapshotJson + "\".", exception);
Defensive patterns

Strategy: validation

Validate before calling

// Java: validate snapshot JSON before deserializing
if (snapshotJson == null || !snapshotJson.startsWith("\"") || !snapshotJson.endsWith("\"")) {
    throw new IllegalArgumentException("Corrupt snapshot, expected JSON string: " + snapshotJson);
}

Try / catch

try {
    controlChecksum = objectMapper.readValue(snapshotJson, String.class);
} catch (JsonProcessingException exception) {
    throw new RuntimeException("Unable to restore snapshot \"" + snapshotJson + "\".", exception);
}

Prevention

When it happens

Trigger: Running verify in QUERY_BANK_SNAPSHOT_MODE where snapshotQueries contains an entry whose snapshot string was truncated, manually edited, double-escaped, or written by a different/incompatible verifier version.

Common situations: Snapshot store (e.g. MySQL query_bank table) edited manually; snapshot saved by a newer verifier with a different serialization; database column truncation cutting the JSON mid-string; copying snapshots between environments with different encodings.

Related errors


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