prestodb/presto · error · PrestoException

GENERIC_USER_ERROR

GENERIC_USER_ERROR

Error message

'%s' is not a valid timestamp literal

What it means

LiteralInterpreter wraps failures while building a SqlTimestamp from a TIMESTAMP literal into GENERIC_USER_ERROR saying the value is not a valid timestamp literal. Thrown when the long value cannot be converted under the session's legacy/non-legacy timestamp settings.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/planner/LiteralInterpreter.java:159

        }
        if (type instanceof DateType) {
            return new SqlDate(((Long) node.getValue()).intValue());
        }
        if (type instanceof TimeType) {
            if (properties.isLegacyTimestamp()) {
                return new SqlTime((long) node.getValue(), properties.getTimeZoneKey());
            }
            return new SqlTime((long) node.getValue());
        }
        if (type instanceof TimestampType) {
            try {
                if (properties.isLegacyTimestamp()) {
                    return new SqlTimestamp((long) node.getValue(), properties.getTimeZoneKey(), MILLISECONDS);
                }
                return new SqlTimestamp((long) node.getValue(), MILLISECONDS);
            }
            catch (RuntimeException e) {
                throw new PrestoException(GENERIC_USER_ERROR, format("'%s' is not a valid timestamp literal", (String) node.getValue()));
            }
        }
        if (type instanceof TimestampWithTimeZoneType) {
            return new SqlTimestampWithTimeZone((long) node.getValue());
        }
        if (type instanceof IntervalDayTimeType) {
            return new SqlIntervalDayTime((long) node.getValue());
        }
        if (type instanceof IntervalYearMonthType) {
            return new SqlIntervalYearMonth(((Long) node.getValue()).intValue());
        }
        if (type.getJavaType().equals(Slice.class)) {
            // DO NOT ever remove toBase64. Calling toString directly on Slice whose base is not byte[] will cause JVM to crash.
            return "'" + VarbinaryFunctions.toBase64((Slice) node.getValue()).toStringUtf8() + "'";
        }

        // We should not fail at the moment; just return the raw value (block, regex, etc) to the user
        return node.getValue();

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Correct the timestamp literal to a valid value the session timezone can represent.
  2. Align the legacy_timestamp session property with the server/connector expectations.
  3. Re-plan/re-submit the query on the same Presto version that produced the plan.

Example fix

// before
SELECT TIMESTAMP '9999-99-99 99:99';
// after
SELECT TIMESTAMP '2026-01-01 00:00:00';
Defensive patterns

Strategy: validation

Validate before calling

try { long millis = Long.parseLong(literalText); java.time.Instant.ofEpochMilli(millis); } catch (NumberFormatException | DateTimeException e) { /* reject literal before evaluation */ }

Type guard

boolean isValidTimestampMillis(long millis) { try { java.time.Instant.ofEpochMilli(millis); return true; } catch (DateTimeException e) { return false; } }

Try / catch

try { return LiteralInterpreter.evaluate(literal, session); } catch (PrestoException e) { if (e.getErrorCode() == StandardErrorCode.GENERIC_USER_ERROR.toErrorCode()) { /* prompt user to fix literal */ } else { throw e; } }

Prevention

When it happens

Trigger: Evaluating a TIMESTAMP literal whose epoch-millis value fails SqlTimestamp construction (e.g. out-of-range or invalid under the session time zone / legacy timestamp mode).

Common situations: Mixed-version plans where literal encoding changed, extreme millisecond values, or legacy_timestamp session property mismatching how the literal was produced.

Related errors


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