apache/beam · error · IllegalArgumentException
Encountered unrecognized Timezone
Error message
Encountered unrecognized Timezone: ${type.getTimezone()} What it means
When converting Arrow timestamp columns, the library parses the timezone string via Joda's DateTimeZone.forID; an unrecognized/invalid timezone ID makes it throw IllegalArgumentException. Arrow timestamps carry a timezone string that must be a valid IANA identifier for the converter to build a correct instant.
Solutions
- Normalize the Arrow timestamp timezone to a valid IANA ID (e.g. 'America/New_York', 'UTC') in the producer
- Use Arrow timestamp without timezone (null) if wall-clock semantics are intended and the schema path supports it
- Pre-parse/validate the timezone with DateTimeZone.forID before conversion and repair invalid IDs
- Convert timestamps to epoch longs upstream and skip the tz-aware branch
Example fix
// before new ArrowType.Timestamp(ArrowType.TimeUnit.MILLISECOND, "UTC+2") // throws // after new ArrowType.Timestamp(ArrowType.TimeUnit.MILLISECOND, "UTC")
Defensive patterns
Strategy: validation
Validate before calling
import org.joda.time.DateTimeZone;
String tzId = timestampField.getType().getTimezone();
try {
DateTimeZone.forID(tzId);
} catch (Exception e) {
throw new IllegalArgumentException("Arrow timestamp timezone not a valid IANA ID: " + tzId);
} Type guard
boolean isValidIANATimezone(String id) {
try { org.joda.time.DateTimeZone.forID(id); return true; } catch (Exception e) { return false; }
} Try / catch
try {
rows = ArrowConversion.rowsFromRecordBatch(schema, batches);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Encountered unrecognized Timezone")) {
throw new ConfigException("Fix the Arrow timestamp timezone ID", e);
}
throw e;
} Prevention
- Always use IANA timezone IDs ('UTC', 'America/New_York'), never offsets or abbreviations
- Validate timezone strings at ingestion boundaries
- Standardize on null-timezone (naive) or 'UTC' Arrow timestamps across producers
When it happens
Trigger: Arrow schema declares a Timestamp field whose getTimezone() is null for a tz-aware conversion path, a non-IANA string (e.g. 'UTC+2', 'GMT-05:00', or a typo like 'Amercia/New_York'), so DateTimeZone.forID fails.
Common situations: Data written by tools that store offset-style or custom timezone labels; null timezone on naive timestamps where the converter expects an ID; cross-version schema drift where the writer emitted an abbreviation like 'EST'.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- There are no more Rows.
- A function must be provided to convert the input type into…
- A PValue contained in
- A schema was provided without a data format (or viceversa)…
- All inherited interfaces of
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/9e4280f08d387406.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/arrow/src/main/java/org/apache/beam/sdk/extensions/arrow/ArrowConversion.java:522
public Optional<Function<Object, Object>> visit(ArrowType.Date type) {
throw new IllegalArgumentException("Type \'" + type.toString() + "\' not supported.");
}
@Override
public Optional<Function<Object, Object>> visit(ArrowType.Time type) {
throw new IllegalArgumentException("Type \'" + type.toString() + "\' not supported.");
}
@Override
public Optional<Function<Object, Object>> visit(ArrowType.Timestamp type) {
// Arrow timestamp semantics:
// - With timezone: epoch is always UTC, timezone is display metadata
// - Without timezone: epoch is in an unknown timezone ("naive" wall-clock time)
DateTimeZone tz;
try {
tz = DateTimeZone.forID(type.getTimezone());
} catch (Exception e) {
throw new IllegalArgumentException(
"Encountered unrecognized Timezone: " + type.getTimezone());
}
return Optional.of(
epoch -> {
switch (type.getUnit()) {
case MILLISECOND:
return new DateTime((long) epoch, tz);
case MICROSECOND:
return new DateTime(Math.floorDiv((long) epoch, 1000L), tz);
case NANOSECOND:
long seconds = Math.floorDiv((long) epoch, 1_000_000_000L);
long nanoAdjustment = Math.floorMod((long) epoch, 1_000_000_000L);
return java.time.Instant.ofEpochSecond(seconds, nanoAdjustment);
default:
throw new AssertionError("Encountered unrecognized TimeUnit: " + type.getUnit());
}
});View on GitHub (pinned to 12126d8942)