No. The pandas documentation warns that loading pickled data received from untrusted sources can be unsafe. A pickle file is a set of instructions that Python runs while it rebuilds objects, so opening someone else's file can execute their code. Use read_pickle only on files you created or can fully verify.
What read_pickle actually does
The signature is simple: pandas.read_pickle(filepath_or_buffer, compression='infer', storage_options=None). The compression default of infer means pandas guesses from the file extension, such as .gz, .zip or .zst, and decompresses before loading. That convenience matters for security because a compressed file hides its contents from a casual look, and the same unpickling step runs after decompression.
Pickle is not a data format in the way CSV or Parquet is. It is a serialization protocol for Python objects, and rebuilding an object can mean calling arbitrary functions. A DataFrame is only one thing it can hold. A file named train.pkl can contain a DataFrame, or it can contain an instruction to run a shell command, and read_pickle will happily follow either.
Where this bites data teams
The risky moments are rarely dramatic. They look like routine work:
- A colleague shares a cached DataFrame on a shared drive that many people can write to.
- A tutorial or competition download ships its data as a pickle.
- A pipeline step reads a pickle from an object storage bucket that a wider group can write to.
- A notebook pulls a file from a public link to save time on feature engineering.
In each case the data scientist is not thinking about code execution. They are thinking about getting the table into memory.
Safer choices for data you receive
If the data crosses a trust boundary, change the format rather than trying to inspect the pickle.
| Situation | Better format | Why |
|---|---|---|
| Tabular data from outside your team | Parquet or CSV | Loading parses values, it does not rebuild arbitrary objects |
| Internal cache, same trust zone | Pickle is acceptable | You wrote it, only your job can write there |
| Arrays | NumPy arrays without object dtype | See our post on numpy load and allow_pickle |
| Model weights | A weights only format | Avoids code in the file |
For internal caches, lock down who can write to the location. A pickle you wrote yourself is only as trustworthy as the folder it sits in.
Steps to take this week
- Search your repos and notebooks for read_pickle, to_pickle and pickle.load.
- For each hit, write down where the file comes from and who can modify that location.
- Replace pickles that cross a team or company boundary with Parquet or CSV.
- For internal pickles, restrict write access and keep the files out of shared public links.
- Add a pull request check that flags new read_pickle calls so someone looks at the source of the file.
For a deeper look at the mechanism, see Python pickle deserialization risk explained and how to inspect a pickle model file without running it.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how a pull request check can stop a risky change before it merges.
Safeguard scans repositories and dependencies and can apply policies and gates on pull requests, so a new unsafe load call can be reviewed before it lands. You can try a free scan at gold.safeguard.sh/scan.
Quick check
Does compressing a pickle make it safer?
No. Compression only changes how the bytes are stored. After pandas decompresses the file, the same unpickling step runs.
Is a pickle I made last month safe to load?
Usually yes, provided nobody else could write to the place you stored it. Trust attaches to the file's whole history, not just to its name.
Sources
Last reviewed: 19 October 2026.