Fix ValueError: unsupported pickle protocol 5

The ValueError: unsupported pickle protocol 5 error happens when an older Python runtime tries to read a pickle file that was written with protocol 5. Protocol 5 was added in Python 3.8, so Python 3.7 and older cannot load that file format directly.

The fix is to match the Python versions or save the file with an older protocol. If you control the system that creates the pickle file, write it with protocol=4 for compatibility with Python 3.4 through 3.7. If you only control the system that loads the file, upgrade that environment to Python 3.8 or newer.

This error is common when a model, cache, or exported object is created on a newer laptop and then moved to an older server. The file extension may still be .pkl, but the internal protocol is newer than the reader understands. Treat the pickle file and the Python runtime as a pair.

Why Protocol 5 Fails

Pickle files include a protocol number. Newer protocols can store objects more efficiently, but older Python versions do not know how to read future protocols. The loading code may look normal, but the file itself was created by a newer interpreter.

import pickle

with open("model.pkl", "rb") as file:
    obj = pickle.load(file)

print(type(obj))

If this fails with protocol 5, inspect the Python version and the highest protocol supported by that runtime. This is the fastest way to confirm whether the problem is the file or the interpreter.

Check Python and Pickle Protocol Support

Run this in the environment that loads the file. Python 3.8 and newer can read protocol 5, while older runtimes cannot.

import pickle
import sys

print(sys.version)
print("Highest pickle protocol:", pickle.HIGHEST_PROTOCOL)

If the highest protocol is 4, that environment cannot load a protocol 5 pickle. Use this Python version guide if you need to confirm which interpreter your script, notebook, or service is actually using.

Save With Protocol 4 for Older Python

When you need to share a pickle file with Python 3.7 or older, save with protocol 4. This is usually the cleanest fix because the reader does not need a custom loader.

import pickle

data = {"name": "example", "values": [1, 2, 3]}

with open("data-py37.pkl", "wb") as file:
    pickle.dump(data, file, protocol=4)

Use binary mode when writing pickle files. This related guide on writing bytes to a file in Python covers the file-mode details behind wb and rb.

Load the Compatible File

After the creator saves with protocol 4, older Python versions can read the file normally. Keep the producer and consumer versions documented so future exports do not silently switch back to protocol 5.

import pickle

with open("data-py37.pkl", "rb") as file:
    data = pickle.load(file)

print(data)

The official pickle documentation covers loading and dumping objects, while the pickle data stream format section explains protocol compatibility.

Convert a Protocol 5 File

If you already have a protocol 5 file, load it once in Python 3.8 or newer, then re-save it with protocol 4 for older consumers. This conversion requires access to a newer Python runtime because the older runtime cannot open the original file.

import pickle
from pathlib import Path

source = Path("protocol5.pkl")
target = Path("protocol4.pkl")

with source.open("rb") as file:
    data = pickle.load(file)

with target.open("wb") as file:
    pickle.dump(data, file, protocol=4)

Do this only with pickle files from trusted sources. Pickle can execute code during loading, so it is not a safe interchange format for untrusted data. If the object is simple data, consider JSON, CSV, Parquet, or another safer format instead. Do not download a random pickle file and load it just to convert the protocol.

Guard Exports in Shared Code

When code runs across several machines, choose the protocol based on the oldest supported Python version. A small helper keeps the choice explicit and avoids accidental incompatibility after someone upgrades their local interpreter.

import pickle

OLDEST_SUPPORTED_PROTOCOL = 4

def dump_for_team(data, path):
    with open(path, "wb") as file:
        pickle.dump(data, file, protocol=OLDEST_SUPPORTED_PROTOCOL)

print("Runtime highest protocol:", pickle.HIGHEST_PROTOCOL)

Protocol 5 was introduced for better out-of-band buffer support, described in PEP 574. Use it when every reader supports Python 3.8 or newer; otherwise choose protocol 4 deliberately.

Quick Fix Checklist

  • Check the loading environment with pickle.HIGHEST_PROTOCOL.
  • Upgrade the reader to Python 3.8 or newer if protocol 5 is required.
  • Save with protocol=4 when older Python versions must read the file.
  • Convert protocol 5 files from a Python 3.8+ environment.
  • Only load pickle files from trusted sources.
  • Document the protocol in team scripts so files are portable across servers.
  • If the failure is about object pickling rather than protocol support, see this guide to can’t pickle local object.
  • Use conditional imports in Python when optional serialization dependencies vary by environment.
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted