Joblib Inspector
See the objects, NumPy arrays and scikit-learn models inside a joblib or pickle file, and which versions it needs to load. The file is read as data; when you want proof, it loads in a real Python sandboxed in this tab.
- Opens
.joblib.pkl.pickle- Compression
- All six joblib codecs
- Test loads in
- Python 3.11 to 3.13
- Uploads
- None
Drop a .joblib or .pkl file here
Read as data in this tab: nothing in the file runs, nothing is uploaded.
See it work
30 seconds: a model opened down to one tree, then a NumPy 2 file converted
How it reads a file without running it
Three steps, from the first bytes to the arrays
joblib.load and pickle.load execute the file: a pickle is a small program that imports names and calls them. This page decodes the same program and stops short of calling anything.
Unpack by content
The first bytes tell zlib, gzip, bz2, lzma, xz and lz4 apart, whatever the file is called. Unpacking stops at 1.5 GB, so a tiny file that would expand forever fails fast.
Decode the program, call nothing
Every opcode of protocols 0 to 5 is decoded. Where Python would import a class and call it, the page keeps a record of the call instead, so you see what loading would do.
Lift the array blocks out
joblib writes each NumPy array’s raw bytes straight into the stream, after a small wrapper record. The page reads them in place: dtype, shape, byte order and Fortran order included.
What you see
The Objects, Compatibility and Stream views, on the sample model
Fragments of the sample model, a scikit-learn pipeline saved with its feature names and test accuracy.
'model' | Pipeline | scikit-learn 1.9.1 |
|---|---|---|
'features' | list | 4 items |
'classes' | list | 3 items |
'metrics' | dict | 3 keys |
'trained_at' | str | '2026-10-28' |
Objects
The object tree with Python paths you can paste into code. Arrays come with statistics and a histogram, estimators with their parameters, coefficients and drawn decision trees.
- Python
- 3.8 or newer
- NumPy
- 1.26 or newer
- joblib
- 1.2 or newer
- scikit-learn
- 1.9.1 (the same version)
Compatibility
What a Python environment needs to load the file, each item with the bytes that prove it and the error you get without it. Versions the file doesn’t record are marked as such.
opcodes 38%array data 58%
7.8 KB, 1,415 opcodes, 21 arrays
Stream
Where the bytes go, and every opcode in order with the array blocks between them, as joblib.load would read them.
What breaks between versions
11 cases, saved and loaded in pinned Python environments
We saved small files in pinned Python environments and loaded them in others. These are the results as observed, not taken from bug reports. The Compatibility tab warns about each case it finds in your file.
| File | Saved with | Loaded with | Result |
|---|---|---|---|
| NumPy scalars and object arrays | NumPy 2.0.0 | NumPy 1.25.2 | ModuleNotFoundError: No module named 'numpy._core' |
| Numeric arrays only | NumPy 2.0.0 | NumPy 1.25.2 | Loads |
| NumPy scalars and object arrays | NumPy 2.0.0 | NumPy 1.26.4 | Loads |
| Decision tree | scikit-learn 1.2.2 | scikit-learn 1.3.0 | ValueError: node array from the pickle has an incompatible dtype |
| Decision tree | scikit-learn 1.2.2 | scikit-learn 1.3.1 | ValueError: node array from the pickle has an incompatible dtype |
| Scaler and logistic regression | scikit-learn 1.2.2 | scikit-learn 1.3.0 | Loads with InconsistentVersionWarning; predictions identical |
| Scaler and logistic regression | scikit-learn 1.9.1 | scikit-learn 1.6.1 | Loads, then predict fails: AttributeError |
| Arrays | joblib 1.4.2 | joblib 1.1.1 | KeyError: 0 |
| Arrays, pickle protocol 5 | Python 3.11.18 | Python 3.7.17 | ValueError: unsupported pickle protocol: 5 |
| Logistic regression | scikit-learn 0.20.4 | scikit-learn 1.9.1 | ModuleNotFoundError: No module named 'sklearn.linear_model.logistic' |
| A payload calling os.system | Python 3.12.16 | Python 3.12.16 | Loads, and runs the command |
Each row is a file generated from source in a Docker image with exact package versions, loaded with no network access, on 2026-11-02.
Limits
What reading a file without running it can and can’t tell you
| Safety | Viewing a file here is safe. Loading it in Python is a different matter: the Imports tab flags the calls exploits use, but scikit-learn and other libraries also run their own code while loading, and no list can prove a file harmless. |
|---|---|
| Versions | Pickles don’t record the Python or NumPy version. The page reports what the bytes prove, such as numpy._core paths or scikit-learn’s stored version, and marks the rest as likely or not recorded. |
| Custom objects | Classes from your own code, pandas DataFrames and similar objects are shown as the state they store, not as Python would rebuild them. |
| Size | Files up to 1 GB, unpacking to at most 1.5 GB; in practice, your device’s memory. Array statistics sample very large arrays. |
| Conversion | One route, proven end to end: data files saved with NumPy 2 that NumPy 1.25 and older can’t load. Models aren’t converted: their internal state belongs to the scikit-learn version that saved them. |
| Test in Python | Five Python builds for the browser (Pyodide), from Python 3.11 with NumPy 1.24 and scikit-learn 1.2 to Python 3.13 with NumPy 2.2 and scikit-learn 1.7. They download from a CDN on first use: 15 to 35 MB, or up to 110 MB with scikit-learn. |
Questions
Why does my model fail to load?
Usually a version mismatch. No module named 'numpy._core' means it was saved with NumPy 2 and you have NumPy 1.25 or older.node array from the pickle has an incompatible dtype means trees saved before scikit-learn 1.3. A module path that no longer exists, such as sklearn.externals.joblib, means a much older scikit-learn. Open the file here and the Compatibility tab names the version to install.
Can it convert my file for an older version?
For files saved with NumPy 2 that hold arrays and plain Python data, yes. The copy refers to numpy.core instead ofnumpy._core, and before you get it the page proves three things in real Python: the original loads in NumPy 2.0, fails in NumPy 1.25, and the copy loads in NumPy 1.25 with every value identical. For models, install the scikit-learn version the Compatibility tab names.
What does “Test in Python” run, and where?
joblib.load on your file, in Python compiled for the browser (Pyodide), inside a sandboxed frame with no network and no access to this page, its storage or your other tabs. The runtime downloads from cdn.jsdelivr.net, and each file is checked against a hash pinned in this site’s code. Your file goes into the sandbox, never out of the tab.
Is it safe to open an untrusted pickle here?
Yes. Opening a file never unpickles it: the bytes are decoded as data in a background worker. “Test in Python” does run the file, in the sandbox described above, and asks first when the file calls something that can run code. Don’t load an untrusted file in your own Python.
Which files can it open?
Files written by joblib.dump in any version since 0.9, compressed or not, plain pickles of protocols 0 to 5, and NumPy.npy files. For joblib 0.9 files that keep arrays in separate .npy files, select all of them together.
Is my file uploaded?
No. It is read with your browser’s File API in a Web Worker. The Network tab of your browser’s developer tools shows no upload; the only downloads are the pinned Python runtime files, and only when you test in Python.
More tools in Data viewers.