python/cpython · error · ValueError
Failed to encode latin1 string when unpickling a time object
Error message
Failed to encode latin1 string when unpickling a time object. pickle.load(data, encoding='latin1') is assumed.
What it means
Raised by time.__new__ during unpickling when the pickle payload's first argument is a 6-character str that cannot be encoded to latin1. Python pickles datetime.time as a byte string; when a pickle created with protocol-level str handling is loaded with an encoding other than latin1 (e.g. pickle.load(data, encoding='utf-8')), the str may contain non-latin1 characters and the reconstruction fails with this explanatory ValueError.
Source
Thrown at Lib/_pydatetime.py:1444
def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0):
"""Constructor.
Arguments:
hour, minute (required)
second, microsecond (default to zero)
tzinfo (default to None)
fold (keyword only, default to zero)
"""
if (isinstance(hour, (bytes, str)) and len(hour) == 6 and
ord(hour[0:1])&0x7F < 24):
# Pickle support
if isinstance(hour, str):
try:
hour = hour.encode('latin1')
except UnicodeEncodeError:
# More informative error message.
raise ValueError(
"Failed to encode latin1 string when unpickling "
"a time object. "
"pickle.load(data, encoding='latin1') is assumed.")
self = object.__new__(cls)
self.__setstate(hour, minute or None)
self._hashcode = -1
return self
hour, minute, second, microsecond, fold = _check_time_fields(
hour, minute, second, microsecond, fold)
_check_tzinfo_arg(tzinfo)
self = object.__new__(cls)
self._hour = hour
self._minute = minute
self._second = second
self._microsecond = microsecond
self._tzinfo = tzinfo
self._hashcode = -1
self._fold = foldView on GitHub (pinned to bc6749cc3b)
Solutions
- Load with pickle.load(f, encoding='latin1') as the message states
- Re-serialize the data in a version-neutral format: JSON ISO strings, or pickle.dumps with the highest protocol in Python 3
- If the source pickle is corrupt, recover field values and reconstruct time objects explicitly
Example fix
# before obj = pickle.load(f, encoding='utf-8') # after obj = pickle.load(f, encoding='latin1')
Defensive patterns
Strategy: try-catch
Validate before calling
if isinstance(v, str) and any(ord(c) > 255 for c in v[:6]) and len(v) == 6:
raise ValueError('non-latin1 payload: load the pickle with encoding=latin1') Try / catch
try:
obj = pickle.load(f, encoding='latin1')
except ValueError:
# payload is not a latin1 pickle; retry default or re-raise
raise Prevention
- Always pass encoding='latin1' when loading Python 2 str-era pickles
- Migrate persisted pickles to protocol >= 4 or to JSON ISO strings
- Never pickle datetime objects through version-mixed pipelines without a migration step
When it happens
Trigger: pickle.loads(data, encoding='utf-8') (or pickle.load with a non-latin1 encoding) on a pickle containing a datetime.time; pickles produced by Python 2 and loaded into Python 3 with the wrong encoding argument; hand-crafted time('\\x89\\x00...') str arguments with chars above U+00FF.
Common situations: Migrating Python 2 pickle archives to Python 3 without the documented encoding='latin1' argument; cross-version data pipelines (Redis/database blob storage of pickles); loading old .pkl files with generic unpickle helpers that pass encoding='utf-8'.
Related errors
- Failed to encode latin1 string when unpickling a datetime ob
- Failed to encode latin1 string when unpickling a date object
- Unknown timespec value
- Invalid ISO string
- Invalid isoformat string
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/dc89d379420464ed.
Report an issue: GitHub.