apache/beam · error · ValueError

dt has no timezone info…

Error message

dt has no timezone info (https://docs.python.org/3/library/datetime.html#aware-and-naive-objects): %s

What it means

from_utc_datetime() requires an offset-aware datetime in UTC. A naive datetime (tzinfo is None) cannot be unambiguously converted to an absolute time, so a ValueError is raised with a link to Python's aware/naive documentation.

Solutions

  1. Attach UTC explicitly: dt.replace(tzinfo=datetime.timezone.utc) for known-UTC naive values
  2. Use datetime.now(datetime.timezone.utc) instead of utcnow()
  3. Parse with an offset: dateutil.parser.isoparse('...Z') then pass the aware result

Example fix

// before
ts = Timestamp.from_utc_datetime(datetime.utcnow())
// after
ts = Timestamp.from_utc_datetime(datetime.now(datetime.timezone.utc))
Defensive patterns

Strategy: validation

Validate before calling

if dt.tzinfo is None:
    dt = dt.replace(tzinfo=datetime.timezone.utc)  # only if known UTC

Type guard

def is_aware(dt: datetime.datetime) -> bool:
    return dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None

Try / catch

try:
    ts = Timestamp.from_utc_datetime(dt)
except ValueError as e:
    if 'no timezone info' in str(e):
        ts = Timestamp.from_utc_datetime(dt.replace(tzinfo=datetime.timezone.utc))
    else:
        raise

Prevention

When it happens

Trigger: Timestamp.from_utc_datetime(datetime.utcnow()) — utcnow() returns naive; Timestamp.from_utc_datetime(datetime.fromisoformat(s)) where s has no offset; parsing user timestamps without a timezone suffix.

Common situations: Using deprecated datetime.utcnow(); log lines like '2024-01-01 00:00:00' with no Z/offset; DB columns of type TIMESTAMP (naive) rather than TIMESTAMPTZ.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/0e33479fcd85fff2. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/utils/timestamp.py:162

          'Cannot interpret %s %s as Timestamp.' % (seconds, type(seconds)))

  @staticmethod
  def now() -> 'Timestamp':
    return Timestamp(seconds=time.time())

  @staticmethod
  def _epoch_datetime_utc() -> datetime.datetime:
    return datetime.datetime.fromtimestamp(0, pytz.utc)

  @classmethod
  def from_utc_datetime(cls, dt: datetime.datetime) -> 'Timestamp':
    """Create a ``Timestamp`` instance from a ``datetime.datetime`` object.

    Args:
      dt: A ``datetime.datetime`` object in UTC (offset-aware).
    """
    if dt.tzinfo is None:
      raise ValueError(
          "dt has no timezone info " +
          "(https://docs.python.org/3/library/datetime.html" +
          "#aware-and-naive-objects): %s" % dt)
    if dt.tzinfo != pytz.utc and dt.tzinfo != datetime.timezone.utc:
      raise ValueError('dt not in UTC: %s' % dt)
    duration = dt - cls._epoch_datetime_utc()
    # Avoid total_seconds(): its float result can be off by a microsecond.
    return Timestamp(
        seconds=duration.days * 86400 + duration.seconds,
        micros=duration.microseconds)

  @classmethod
  def from_rfc3339(cls, rfc3339: str) -> 'Timestamp':
    """Create a ``Timestamp`` instance from an RFC 3339 compliant string.

    Fractional seconds up to microseconds produce a microsecond-precision
    Timestamp; a longer fraction (up to nanoseconds) produces a Timestamp
    whose precision matches the number of fractional digits.

View on GitHub (pinned to 12126d8942)