Main Ecosystems
HomePython CorePandas ReferenceNumPy ScientificFastAPI & PydanticDjango Enterprise
More Ecosystems
Environment & SetupRequests & HTTPAsyncIO ConcurrencyObject-Oriented OOPPyTorch Deep LearningScikit-Learn MLFlask FrameworkWeb ScrapingDatabase & ORMDevOps & Docker

UnpicklingError: magic_number = pickle_module.load(f) in Pandas

Verified FixPython 3.10+Pandas 2.2+Silo: pandas

Quick Fix / Solution Rapide

Verify that the file is not empty or corrupted, ensure Python/Pandas version compatibility, or migrate to modern Parquet format with pd.read_parquet().

Root Cause Analysis

This error occurs when Python tries to deserialize a file or byte stream using pd.read_pickle() or pickle.load(), but the binary stream lacks a valid pickle protocol header (magic number).

1. File Corruption or Truncated File Writes

If a process writing a pickle file is interrupted (out-of-memory crash, disk space exhaustion, or unclosed file handle), the resulting file will be truncated. When pickle.load() attempts to read the initial header bytes, it finds invalid data and raises UnpicklingError.

2. Passing Non-Pickle Files (HTML, CSV, or Text)

Attempting to load an HTML error page (e.g. 404 from a failed download) or a plain text CSV with pd.read_pickle() fails immediately because the file does not start with the pickle opcode byte sequences.

3. Incompatible Pickle Protocols Between Python Versions

Pickle files serialized with newer protocols (e.g. Protocol 5 introduced in Python 3.8) cannot be unpickled by older Python runtimes without backports.

4. Git LFS Pointer Files

When cloning a repository with Git LFS without running git lfs pull, the pickle file will merely contain a small plain text pointer string.

Reproduction Code (MCVE)

Example: Bug Reproduction
import io
import pickle

# Attempting to unpickle arbitrary plain text bytes without pickle header
corrupted_bytes = io.BytesIO(b'<!DOCTYPE html><html><body>404 Not Found</body></html>')
pickle.load(corrupted_bytes)

Solution 1: Properly Serialize and Deserialize DataFrame Buffers

Ensure DataFrame serialization is completed with proper context managers and valid protocol headers.

Example: Recommended Solution
import io
import pandas as pd

df = pd.DataFrame({'id': [1, 2, 3], 'value': [10.5, 20.3, 30.1]})

# Serialize to binary buffer
buffer = io.BytesIO()
df.to_pickle(buffer)
buffer.seek(0)

# Safely deserialize
loaded_df = pd.read_pickle(buffer)
print('DataFrame unpickled successfully:')
print(loaded_df)

Solution 2: Use Standardized JSON Format for Data Exchange

Use standardized JSON serialization (to_json() / read_json()) which avoids Python pickle security risks and binary format corruption.

Example: Alternative Solution
import io
import pandas as pd

df = pd.DataFrame({'id': [1, 2, 3], 'value': [10.5, 20.3, 30.1]})

buffer = io.StringIO()
df.to_json(buffer, orient='split')
buffer.seek(0)

json_df = pd.read_json(buffer, orient='split')
print('JSON data loaded successfully:')
print(json_df)

A common security and maintenance mistake is using pickle for long-term data storage or API transfers. Pickle files are neither secure against arbitrary code execution nor guaranteed to remain readable across different major library releases. Always prefer Parquet or Feather formats in production data pipelines. An edge case occurs when opening pickle files in text mode (open(filename, 'r')) rather than binary mode ('rb'). Text mode will corrupt byte sequences on Windows (CRLF translation). Always pass 'rb'. Contrast this error with EOFError: Ran out of input, which occurs when the file is completely 0 bytes.