python/cpython · error · ValueError
Failed to encode latin1 string when unpickling a date object
Error message
Failed to encode latin1 string when unpickling a date object. pickle.load(data, encoding='latin1') is assumed.
What it means
Raised by date.__new__ during unpickling: the 4-byte pickled date string could not be encoded to latin1. Pickles created with protocol < 2 (or loaded with encoding='latin1' semantics) store dates as 4-byte strings; if the bytes contain non-latin1-encodable code points, the string is corrupt and reconstruction fails with this ValueError instead of a cryptic UnicodeEncodeError.
Source
Thrown at Lib/_pydatetime.py:1007
__slots__ = '_year', '_month', '_day', '_hashcode'
def __new__(cls, year, month=None, day=None):
"""Constructor.
Arguments:
year, month, day (required, base 1)
"""
if (month is None and
isinstance(year, (bytes, str)) and len(year) == 4 and
1 <= ord(year[2:3]) <= 12):
# Pickle support
if isinstance(year, str):
try:
year = year.encode('latin1')
except UnicodeEncodeError:
# More informative error message.
raise ValueError(
"Failed to encode latin1 string when unpickling "
"a date object. "
"pickle.load(data, encoding='latin1') is assumed.")
self = object.__new__(cls)
self.__setstate(year)
self._hashcode = -1
return self
year, month, day = _check_date_fields(year, month, day)
self = object.__new__(cls)
self._year = year
self._month = month
self._day = day
self._hashcode = -1
return self
# Additional constructors
@classmethodView on GitHub (pinned to bc6749cc3b)
Solutions
- Load legacy pickles with pickle.load(f, encoding='latin1') as the message instructs
- Regenerate the pickle from the original data source if it is corrupt
- Prefer pickle protocol >= 2 (or JSON) for cross-version/transport-safe serialization
Example fix
# before obj = pickle.load(f) # protocol-0 pickle from Python 2 # after obj = pickle.load(f, encoding='latin1')
Defensive patterns
Strategy: try-catch
Try / catch
try:
obj = pickle.loads(data)
except ValueError as e:
if 'latin1' in str(e):
obj = pickle.loads(data, encoding='latin1')
else:
raise Prevention
- Load Python-2-era pickles with pickle.load(f, encoding='latin1')
- Use protocol >= 2 or JSON for pickles crossing versions/transports
- Verify pickle integrity (checksums) when data comes from untrusted storage
When it happens
Trigger: pickle.load on data not produced by pickle (truncated or tampered date pickles); loading protocol-0/1 pickles across encodings where the 4-char date string was damaged; hand-crafting date(string) calls that match the pickle shape (len 4, month byte 1..12).
Common situations: Reading pickles from untrusted or corrupted sources; pickles transferred through channels that mangled non-ASCII bytes (e.g. decoded as UTF-8 then re-encoded); legacy Python 2 pickles loaded with wrong encoding parameter.
Related errors
- Failed to encode latin1 string when unpickling a time object
- Failed to encode latin1 string when unpickling a datetime ob
- Unknown timespec value
- Invalid ISO string
- Invalid isoformat string
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/cb75d67195f0b1e9.
Report an issue: GitHub.