Safeguard
Developer Tools•

Pickle alternatives for ML checkpoints, compared

Safetensors, JSON, MessagePack, Protobuf and others avoid pickle's code execution risk. Here is how to choose a format for storing and sharing model data.

Safeguard Security Team
3 min read

For model weights, safetensors is the usual replacement for pickle because it stores raw tensors with a small header and nothing to execute. For configuration and metadata, JSON works. Formats like MessagePack, Protobuf, Cap'n Proto and Avro are general purpose options. The right choice depends on what you are storing.

Why leave pickle at all

Python's documentation says pickle is not secure and that a crafted pickle can execute arbitrary code when loaded. Hugging Face's documentation explains the mechanism: opcodes such as GLOBAL and REDUCE let a file import and call functions, including builtins like exec. Its first mitigation is simply to not use pickle.

The Hub's page also names alternatives: MessagePack, Protobuf, Cap'n Proto, Avro and safetensors, and says TensorFlow and Flax checkpoints are not affected by this specific issue.

Choosing by what you store

  • Model weights, tensors only: safetensors. Designed to be safe and fast, supports loading part of a file.
  • Weights plus metadata for local inference: GGUF. Encodes tensors and a standard set of metadata.
  • Settings, labels, small structures: JSON. The Python docs recommend it for untrusted data.
  • Structured records with a schema: Protobuf, Avro or Cap'n Proto. Listed by the Hub as alternatives, and schema driven.
  • Compact general data: MessagePack. Listed by the Hub as an alternative to pickle.
  • Arbitrary Python objects: avoid. This is what pickle is for, and the risk.

Trade-offs to know

JSON. The Python docs say deserializing untrusted JSON does not by itself create an arbitrary code execution vulnerability. It is text, human readable and interoperable, but handles only a subset of types and no custom classes by default.

safetensors. Tensors only. Not a place for custom classes or optimizer objects in one file, so you may split state across files.

GGUF. The Hub describes it as encoding tensors plus metadata, aimed at inference with GGML based tools. I did not find security claims for it on the page, so apply the same review habits as for any downloaded file.

Schema formats. Good when different languages share data. They need a schema you maintain.

A format that cannot hold code removes one risk, not all. Bugs in parsers exist in any format, so keep libraries current.

If you must keep pickle

Restrict the loader, as in torch.load weights_only, disassemble first as in inspecting a pickle file, and use the Python docs' option of signing data with hmac if you need integrity for data you produced yourself.

Quick check

Can I just convert every pickle checkpoint to safetensors?

For tensors, usually yes. Do the conversion in a sandbox, since reading the original is the risky step, and keep non-tensor state elsewhere.

Is JSON good for model weights?

It is safe to parse but a poor fit for large tensors. Use it for configuration and metadata.

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.