prestodb/presto · error · PrestoException

INVALID_CAST_ARGUMENT

INVALID_CAST_ARGUMENT

Error message

Value cannot be cast to time: 

What it means

Thrown by the VARCHAR->TIME cast implementation (castFromSlice) when the string cannot be parsed as a time-without-time-zone value. parseTimeWithoutTimeZone throws IllegalArgumentException and Presto wraps it as INVALID_CAST_ARGUMENT, meaning the literal is not a valid 'HH:mm:ss[.fff]' style time.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/type/TimeOperators.java:182

            return utf8Slice(printTimeWithoutTimeZone(value));
        }
    }

    @ScalarOperator(CAST)
    @LiteralParameters("x")
    @SqlType(StandardTypes.TIME)
    public static long castFromSlice(SqlFunctionProperties properties, @SqlType("varchar(x)") Slice value)
    {
        try {
            if (properties.isLegacyTimestamp()) {
                return parseTimeWithoutTimeZone(properties.getTimeZoneKey(), value.toStringUtf8());
            }
            else {
                return parseTimeWithoutTimeZone(value.toStringUtf8());
            }
        }
        catch (IllegalArgumentException e) {
            throw new PrestoException(INVALID_CAST_ARGUMENT, "Value cannot be cast to time: " + value.toStringUtf8(), e);
        }
    }

    @ScalarOperator(HASH_CODE)
    @SqlType(StandardTypes.BIGINT)
    public static long hashCode(@SqlType(StandardTypes.TIME) long value)
    {
        return AbstractLongType.hash(value);
    }

    @ScalarOperator(XX_HASH_64)
    @SqlType(StandardTypes.BIGINT)
    public static long xxHash64(@SqlType(StandardTypes.TIME) long value)
    {
        return XxHash64.hash(value);
    }

    @ScalarOperator(IS_DISTINCT_FROM)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Normalize the string to ISO 'HH:mm:ss' format before casting (date_parse/regexp operations).
  2. Use try_cast(col AS TIME) and coalesce to NULL or a default for unparseable rows.
  3. Inspect the offending value in the message and fix the source data / parsing expression.
  4. If values carry a timezone or date portion, cast to TIMESTAMP or TIME WITH TIME ZONE instead.

Example fix

// before
SELECT CAST(event_time AS TIME) FROM events; -- '9:30 AM'
// after
SELECT CAST(date_format(date_parse(event_time, '%h:%i %p'), '%H:%i:%s') AS TIME) FROM events;
Defensive patterns

Strategy: try-catch

Validate before calling

-- Guard: regex check for strict HH:mm:ss format before casting
SELECT * FROM t WHERE regexp_like(time_str, '^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]{1,9})?$');

Type guard

SELECT CASE WHEN regexp_like(time_str, '^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]+)?$')
       THEN CAST(time_str AS TIME) END AS safe_time FROM t;

Try / catch

// JDBC
try { rs = stmt.executeQuery(timeCastSql); }
catch (SQLException e) {
  if (e.getMessage() != null && e.getMessage().contains("Value cannot be cast to time")) {
    // log offending value from message; rerun with try_cast
  } else throw e;
}

Prevention

When it happens

Trigger: CAST(varchar_col AS TIME) or CREATE TABLE ... AS with string literals where the text is not a parseable time, e.g. '25:00', '12:60:00', 'morning', or includes an unexpected timezone/date part.

Common situations: Loading CSV/object-store data where time strings vary in format ('9:30 AM' vs '09:30:00'); upstream systems exporting localized times; values with trailing whitespace or stray characters.

Related errors


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