Safeguard
Security Guides•

Does numpy.load run code? What allow_pickle controls

numpy.load runs code only when you allow pickled object arrays. What allow_pickle defaults to, what .npy and .npz files hold, and how to load safely.

Safeguard Security Team
4 min read

Not by default. In current NumPy, numpy.load has allow_pickle set to False, so a file containing object arrays fails with a ValueError instead of running pickle. The risk returns when someone passes allow_pickle=True to open an object array, because NumPy then uses the pickle module, which is not secure against malicious data.

What the setting does

The NumPy documentation states that loading files containing object arrays uses the pickle module, which "is not secure against erroneous or maliciously constructed data." It suggests passing allow_pickle=False when you know the data should not contain object arrays. The documented default is False, and with it, a file that holds an object array raises a ValueError.

Plain numeric arrays, such as floats, integers and booleans, do not need pickle. Object arrays do, because each element can be any Python object, and NumPy stores those through pickle.

Why people turn it on anyway

The usual path to a risky load is an error message. A script fails with a message about object arrays, a search result says to add allow_pickle=True, and the fix goes into the notebook. The error was a signal that the file holds something other than plain numbers. Silencing it removes the protection exactly when the file is unusual.

Datasets saved from older code are a common cause. Someone saved a list of variable length records with np.save, NumPy wrapped them in an object array, and every consumer since has needed the flag.

Safer ways to load data

OptionWhen to use it
Keep allow_pickle FalseDefault for any file from outside your team
Re-save as numeric arraysWhen you control the producer, use fixed shape arrays
Use a different containerParquet, or one array per file in an npz archive
Allow pickle on trusted files onlyYour own files, from a location only your jobs write to

An npz file is an archive of arrays. The load call returns a dictionary like object, and the docs say to close it to avoid leaking file descriptors, or to use it as a context manager. Closing it is a hygiene point, not a security control, but it keeps long running notebooks tidy.

The mmap_mode parameter maps a file from disk instead of reading it all into memory. It helps with large arrays. It does not change the pickle behavior, so do not treat it as a safety setting.

Steps for a team

  1. Search for allow_pickle=True across code and notebooks.
  2. For each use, record where the file comes from and who can write to that location.
  3. Convert object arrays to numeric arrays or another format where you control the producer.
  4. Add a review rule so a new allow_pickle=True needs a named reason in the pull request.
  5. Keep untrusted downloads in a separate folder that no training job reads from.

This sits alongside the related guidance in is pandas read_pickle safe for files you did not create.

Safeguard's code and dependency scanning can surface unsafe load patterns in a repository, and its policies and gates can hold a pull request for review. You can run a free scan at gold.safeguard.sh/scan.

Quick check

Is an npy file always safe to load in current NumPy?

Safe from pickle execution while allow_pickle stays False, because object arrays are refused. It can still be a very large file, so size limits matter.

Does a ValueError about object arrays mean the file is malicious?

No. It means the file holds object data, which is common in old research code. Treat it as a reason to check where the file came from.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.