pola-rs/polars · critical

timezone " " cannot be parsed (feature chrono-tz is not…

Error message

timezone "{}" cannot be parsed (feature chrono-tz is not active)

What it means

This panic comes from the fallback implementation of temporal timezone conversion in polars-arrow that is compiled when the optional `chrono-tz` feature is NOT enabled. The function is the stub used in place of the real converter: any attempt to interpret a timestamp in a named timezone (e.g. "America/New_York") hits this panic because the IANA timezone database is only available with the feature active. It is a hard panic, not a Result error, so it aborts the compute operation.

Solutions

  1. Enable the feature in Cargo.toml: polars-arrow = { version = "...", features = ["chrono-tz"] } (or polars with `features = ["temporal", "chrono-tz"]`).
  2. If features are not an option, use a fixed-offset timezone (e.g. "+02:00") instead of a named IANA zone, since FixedOffset parsing does not require chrono-tz.
  3. Check `cargo tree -e features -p polars-arrow` to confirm `chrono-tz` is actually activated; another dependency may disable default features and prune it.
  4. Wrap .dt timezone operations behind a runtime check that the build supports chrono-tz before exposing the functionality.

Example fix

// before (Cargo.toml)
polars = { version = "0.x", default-features = false, features = ["lazy"] }
// after
polars = { version = "0.x", default-features = false, features = ["lazy", "temporal", "chrono-tz"] }
Defensive patterns

Strategy: validation

Validate before calling

// Cargo.toml check before using tz-aware dt ops
fn assert_chrono_tz_available() {
    #[cfg(not(feature = "chrono-tz"))]
    compile_error!("chrono-tz feature required for named-timezone operations");
}
// or at runtime: avoid named tz strings unless feature is on

Type guard

fn uses_named_timezone(tz: &str) -> bool {
    !(tz.starts_with('+') || tz.starts_with('-') || tz.eq_ignore_ascii_case("UTC"))
}

Try / catch

// panic, not Result — isolate with catch_unwind if needed
let result = std::panic::catch_unwind(|| extract_with_tz(&arr, tz));

Prevention

When it happens

Trigger: Calling temporal compute functions like extract_impl/chronotype conversion (e.g. Datetime `.dt.year()`-style operations in polars-arrow) on a PrimitiveArray whose Datetime logical type carries a named timezone string while the `chrono-tz` cargo feature is disabled.

Common situations: Using polars-arrow (or polars built without default features) with `default-features = false` and forgetting to add the `chrono-tz` feature; running timestamp-with-timezone operations in a slimmed-down dependency tree; Cargo workspace feature unification unexpectedly dropping the feature.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/cc6e7516f3ca632a. Report an issue: GitHub.

Appendix: source

Thrown at crates/polars-arrow/src/compute/temporal.rs:282

    O: NativeType,
    F: Fn(chrono::DateTime<chrono_tz::Tz>) -> O,
{
    let timezone = parse_offset_tz(timezone_str)?;
    Ok(extract_impl(array, time_unit, timezone, op))
}

#[cfg(not(feature = "chrono-tz"))]
fn chrono_tz<F, O>(
    _: &PrimitiveArray<i64>,
    _: TimeUnit,
    timezone_str: &str,
    _: F,
) -> PolarsResult<PrimitiveArray<O>>
where
    O: NativeType,
    F: Fn(chrono::DateTime<chrono::FixedOffset>) -> O,
{
    panic!(
        "timezone \"{}\" cannot be parsed (feature chrono-tz is not active)",
        timezone_str
    )
}

fn extract_impl<T, A, F>(
    array: &PrimitiveArray<i64>,
    time_unit: TimeUnit,
    timezone: T,
    extract: F,
) -> PrimitiveArray<A>
where
    T: chrono::TimeZone,
    A: NativeType,
    F: Fn(chrono::DateTime<T>) -> A,
{
    let timestamp_to_datetime_opt: fn(i64) -> Option<chrono::NaiveDateTime> = match time_unit {
        TimeUnit::Second => timestamp_s_to_datetime_opt,

View on GitHub (pinned to fe841f959e)