{"record":{"id":"304c1250d1d0c1b0","repo":"python/cpython","slug":"failed-to-encode-latin1-string-when-unpickling-a-d-304c12","errorCode":null,"errorMessage":"Failed to encode latin1 string when unpickling a datetime object. pickle.load(data, encoding='latin1') is assumed.","messagePattern":"Failed to encode latin1 string when unpickling a datetime object\\. pickle\\.load\\(data, encoding='latin1'\\) is assumed\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pydatetime.py","lineNumber":1800,"sourceCode":"class datetime(date):\n    \"\"\"A combination of a date and a time.\n\n    The year, month and day arguments are required. tzinfo may be None, or an\n    instance of a tzinfo subclass. The remaining arguments may be ints.\n    \"\"\"\n    __slots__ = time.__slots__\n\n    def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0,\n                microsecond=0, tzinfo=None, *, fold=0):\n        if (isinstance(year, (bytes, str)) and len(year) == 10 and\n            1 <= ord(year[2:3])&0x7F <= 12):\n            # Pickle support\n            if isinstance(year, str):\n                try:\n                    year = bytes(year, 'latin1')\n                except UnicodeEncodeError:\n                    # More informative error message.\n                    raise ValueError(\n                        \"Failed to encode latin1 string when unpickling \"\n                        \"a datetime object. \"\n                        \"pickle.load(data, encoding='latin1') is assumed.\")\n            self = object.__new__(cls)\n            self.__setstate(year, month)\n            self._hashcode = -1\n            return self\n        year, month, day = _check_date_fields(year, month, day)\n        hour, minute, second, microsecond, fold = _check_time_fields(\n            hour, minute, second, microsecond, fold)\n        _check_tzinfo_arg(tzinfo)\n        self = object.__new__(cls)\n        self._year = year\n        self._month = month\n        self._day = day\n        self._hour = hour\n        self._minute = minute\n        self._second = second","sourceCodeStart":1782,"sourceCodeEnd":1818,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pydatetime.py#L1782-L1818","documentation":"Raised by datetime.__new__ during unpickling when the 10-character str payload cannot be encoded to latin1. Datetimes are pickled as a compact byte string; loading such a pickle with a non-latin1 encoding (e.g. encoding='utf-8') can yield a str with characters above U+00FF, and reconstruction aborts with this ValueError telling you the assumed encoding.","triggerScenarios":"pickle.load(f, encoding='utf-8') on a pickle containing a datetime.datetime; Python 2 pickles of datetimes loaded into Python 3 with the wrong encoding argument; pickle tools/streams that decode payload strings to utf-8 by default.","commonSituations":"Python 2 -> 3 data migrations of pickled records; cached pickles in files/Redis/DBs written by old interpreters; generic unpickle helpers defaulting encoding to 'utf-8'.","solutions":["Load with encoding='latin1': pickle.load(f, encoding='latin1')","Re-pickle everything in Python 3 (protocol 4+) or migrate storage to ISO-format JSON","Write a one-time conversion script that loads with latin1 and re-dumps safely"],"exampleFix":"# before\nobj = pickle.load(f, encoding='utf-8')\n\n# after\nobj = pickle.load(f, encoding='latin1')","handlingStrategy":"try-catch","validationCode":"if isinstance(v, str) and len(v) == 10 and any(ord(c) > 255 for c in v[:3]):\n    raise ValueError('non-latin1 datetime payload; use encoding=latin1')","typeGuard":null,"tryCatchPattern":"try:\n    obj = pickle.load(f, encoding='latin1')\nexcept ValueError:\n    # not a latin1-encoded pickle after all; surface clearly\n    raise","preventionTips":["Load legacy pickles with encoding='latin1' per the stdlib contract","Migrate pickled archives to protocol >= 4 or JSON once, then drop the legacy path","Version your persisted payloads so decode strategy is explicit"],"tags":["datetime","pickle","valueerror","python2-migration","encoding"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}