prestodb/presto · error · InvalidFunctionArgumentException
Invalid offset minutes %s
Error message
Invalid offset minutes %s
What it means
TimeZoneKey.getTimeZoneKeyForOffset resolves time zones expressed as minute offsets (e.g. +05:30). Offsets must lie within OFFSET_TIME_ZONE_MIN..OFFSET_TIME_ZONE_MAX (±14 hours, in minutes); anything outside throws InvalidFunctionArgumentException with "Invalid offset minutes %s". Valid in-range offsets map into the precomputed OFFSET_TIME_ZONE_KEYS table.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/type/TimeZoneKey.java:147
TimeZoneKey zoneKey = ZONE_ID_TO_KEY.get(zoneId.toLowerCase(ENGLISH));
if (zoneKey == null) {
zoneKey = ZONE_ID_TO_KEY.get(normalizeZoneId(zoneId));
}
if (zoneKey == null) {
throw new TimeZoneNotSupportedException(zoneId);
}
return zoneKey;
}
public static TimeZoneKey getTimeZoneKeyForOffset(long offsetMinutes)
{
if (offsetMinutes == 0) {
return UTC_KEY;
}
if (!(offsetMinutes >= OFFSET_TIME_ZONE_MIN && offsetMinutes <= OFFSET_TIME_ZONE_MAX)) {
throw new InvalidFunctionArgumentException(format("Invalid offset minutes %s", offsetMinutes));
}
TimeZoneKey timeZoneKey = OFFSET_TIME_ZONE_KEYS[((int) offsetMinutes) - OFFSET_TIME_ZONE_MIN];
if (timeZoneKey == null) {
throw new TimeZoneNotSupportedException(zoneIdForOffset(offsetMinutes));
}
return timeZoneKey;
}
private final String id;
private final short key;
public TimeZoneKey(String id, short key)
{
this.id = requireNonNull(id, "id is null");
if (key < 0) {
throw new IllegalArgumentException("key is negative");
}View on GitHub (pinned to 55bb57d202)
Solutions
- Validate the offset is within [-840, 840] minutes before calling getTimeZoneKeyForOffset.
- Parse zone strings with zoneIdForOffset/getTimeZoneKey and catch InvalidFunctionArgumentException to reject bad input.
- Normalize offsets exceeding ±14h (the ISO max) — treat them as invalid user data.
Example fix
// before
TimeZoneKey key = TimeZoneKey.getTimeZoneKeyForOffset(offsetMinutes);
// after
if (offsetMinutes < -840 || offsetMinutes > 840) throw new IllegalArgumentException("offset out of range");
TimeZoneKey key = TimeZoneKey.getTimeZoneKeyForOffset(offsetMinutes); Defensive patterns
Strategy: validation
Validate before calling
if (offsetMinutes != 0 && (offsetMinutes < -840 || offsetMinutes > 840)) throw new IllegalArgumentException("offset out of supported ±14h range"); Type guard
boolean isValidOffsetMinutes(long m) { return m == 0 || (m >= -840 && m <= 840); } Try / catch
try { TimeZoneKey.getTimeZoneKeyForOffset(offsetMinutes); } catch (InvalidFunctionArgumentException e) { /* reject or normalize the offset */ } Prevention
- Validate offsets against the ±14-hour ISO limit at input parsing time.
- Sanitize session time zone strings from clients before converting to offsets.
- Reject rather than wrap offsets beyond the supported range — they indicate corrupt input.
When it happens
Trigger: Calling getTimeZoneKeyForOffset(offsetMinutes) with offsetMinutes outside ±14h range (offsetMinutes < -840 or > 840, excluding 0 which returns UTC_KEY).
Common situations: Parsing malformed session zone strings like '+25:00'; deserializing corrupted offsets from clients or stored plans; connectors converting arbitrary user input to offsets without validation.
Related errors
- Invalid value [%s]. Valid values: %s
- CLICKHOUSE_QUERY_GENERATOR_FAILURE
- Invalid token URI:
- Type must be a TimestampType for TimeStampMilliTZVector
- DRUID_QUERY_GENERATOR_FAILURE
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/452dee9c05bac6e7.
Report an issue: GitHub.