Error database

UnpicklingError: Weights only load failed (torch.load)

PyTorch 2.6 made torch.load refuse arbitrary pickled objects by default. For files you trust, pass weights_only=False; for your own pipelines, save plain state_dicts so the safe default works.

The message you saw
UnpicklingError: Weights only load failed (torch.load)

By Updated

The error

Output
_pickle.UnpicklingError: Weights only load failed. This file can still be loaded, to do so you have two options, do those steps only if you trust the source of the checkpoint.
    (1) In PyTorch 2.6, we changed the default value of the `weights_only` argument in `torch.load` from `False` to `True`. Re-running `torch.load` with `weights_only` set to `False` will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source.
    (2) Alternatively, to load with `weights_only=True` please check the recommended steps in the following link. It first offers a way to allowlist the objects being loaded.
WeightsUnpickler error: Unsupported global: GLOBAL numpy.core.multiarray._reconstruct was not an allowed global by default.

The "Unsupported global" line names whatever object tripped the check — a NumPy internal, argparse.Namespace, or a custom class.

What it means

Checkpoint files saved by torch.save use pickle, a format that can embed executable code. Loading a malicious checkpoint can therefore run an attacker's code. PyTorch 2.6 (January 2025) flipped torch.load to a safe mode by default: only plain tensors and a small allowlist of types load; everything else is refused. Your file contains an object outside that allowlist. The file is probably fine — the default changed underneath it.

Why it happens

Older training scripts saved rich checkpoint dicts: model weights plus the optimizer, the args namespace, NumPy scalars for the best metric, and so on. Any of those non-tensor objects triggers the refusal under the new default. The error also appears when following pre-2025 tutorials whose code assumed the old behaviour.

How to fix it

1. For a file you created, or fully trust, load with the old behaviour.

python
ckpt = torch.load("checkpoint.pt", map_location="cpu", weights_only=False)

This is exactly as safe as torch.load was for years — meaning: safe for your own files, dangerous for files from the internet. Never do this to a checkpoint downloaded from an untrusted account.

2. Better for shared code: allowlist the specific types.

python
import numpy as np
torch.serialization.add_safe_globals([np.core.multiarray._reconstruct])
ckpt = torch.load("checkpoint.pt", map_location="cpu")

Add whatever the "Unsupported global" line names. The safe mode stays on for everything else.

3. Best long-term: save nothing but tensors.

python
torch.save({
    "model": model.state_dict(),
    "optimizer": optimizer.state_dict(),
    "epoch": epoch,                     # plain int — fine
    "best_acc": float(best_acc),        # convert NumPy scalars to Python floats
}, "checkpoint.pt")

State dicts, ints, floats and strings all load under the safe default. This future-proofs your checkpoints.

4. For distributing weights, prefer safetensors. The safetensors format cannot contain code at all, loads faster, and is what Hugging Face uses. No trust decision needed by your users.

How to prevent it

Audit what goes into torch.save — each exotic object is a future loading problem. Treat weights_only=False like allow_pickle=True in NumPy: a deliberate trust statement about a specific file, written next to a comment saying where that file comes from.