{"record":{"id":"cb75d67195f0b1e9","repo":"python/cpython","slug":"failed-to-encode-latin1-string-when-unpickling-a-d","errorCode":null,"errorMessage":"Failed to encode latin1 string when unpickling a date object. pickle.load(data, encoding='latin1') is assumed.","messagePattern":"Failed to encode latin1 string when unpickling a date object\\. pickle\\.load\\(data, encoding='latin1'\\) is assumed\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pydatetime.py","lineNumber":1007,"sourceCode":"    __slots__ = '_year', '_month', '_day', '_hashcode'\n\n    def __new__(cls, year, month=None, day=None):\n        \"\"\"Constructor.\n\n        Arguments:\n\n        year, month, day (required, base 1)\n        \"\"\"\n        if (month is None and\n            isinstance(year, (bytes, str)) and len(year) == 4 and\n            1 <= ord(year[2:3]) <= 12):\n            # Pickle support\n            if isinstance(year, str):\n                try:\n                    year = year.encode('latin1')\n                except UnicodeEncodeError:\n                    # More informative error message.\n                    raise ValueError(\n                        \"Failed to encode latin1 string when unpickling \"\n                        \"a date object. \"\n                        \"pickle.load(data, encoding='latin1') is assumed.\")\n            self = object.__new__(cls)\n            self.__setstate(year)\n            self._hashcode = -1\n            return self\n        year, month, day = _check_date_fields(year, month, day)\n        self = object.__new__(cls)\n        self._year = year\n        self._month = month\n        self._day = day\n        self._hashcode = -1\n        return self\n\n    # Additional constructors\n\n    @classmethod","sourceCodeStart":989,"sourceCodeEnd":1025,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pydatetime.py#L989-L1025","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"# before\nobj = pickle.load(f)  # protocol-0 pickle from Python 2\n# after\nobj = pickle.load(f, encoding='latin1')","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    obj = pickle.loads(data)\nexcept ValueError as e:\n    if 'latin1' in str(e):\n        obj = pickle.loads(data, encoding='latin1')\n    else:\n        raise","preventionTips":["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"],"tags":["datetime","valueerror","pickle","serialization"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}