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
The sample iris model is opened, its pipeline is expanded to the first tree of the random forest, which is drawn with its splits and class mix, and the Compatibility tab lists what loading it needs. Then a file saved with NumPy 2 is converted for NumPy 1.x, and all four checks pass in Python 3.12 with NumPy 2.0 and Python 3.11 with NumPy 1.25. Recorded automatically from this page.

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.

  1. 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.

  2. 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.

  3. 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'Pipelinescikit-learn 1.9.1
'features'list4 items
'classes'list3 items
'metrics'dict3 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.

FileSaved withLoaded withResult
NumPy scalars and object arraysNumPy 2.0.0NumPy 1.25.2ModuleNotFoundError: No module named 'numpy._core'
Numeric arrays onlyNumPy 2.0.0NumPy 1.25.2Loads
NumPy scalars and object arraysNumPy 2.0.0NumPy 1.26.4Loads
Decision treescikit-learn 1.2.2scikit-learn 1.3.0ValueError: node array from the pickle has an incompatible dtype
Decision treescikit-learn 1.2.2scikit-learn 1.3.1ValueError: node array from the pickle has an incompatible dtype
Scaler and logistic regressionscikit-learn 1.2.2scikit-learn 1.3.0Loads with InconsistentVersionWarning; predictions identical
Scaler and logistic regressionscikit-learn 1.9.1scikit-learn 1.6.1Loads, then predict fails: AttributeError
Arraysjoblib 1.4.2joblib 1.1.1KeyError: 0
Arrays, pickle protocol 5Python 3.11.18Python 3.7.17ValueError: unsupported pickle protocol: 5
Logistic regressionscikit-learn 0.20.4scikit-learn 1.9.1ModuleNotFoundError: No module named 'sklearn.linear_model.logistic'
A payload calling os.systemPython 3.12.16Python 3.12.16Loads, 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
SafetyViewing 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.
VersionsPickles 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 objectsClasses from your own code, pandas DataFrames and similar objects are shown as the state they store, not as Python would rebuild them.
SizeFiles up to 1 GB, unpacking to at most 1.5 GB; in practice, your device’s memory. Array statistics sample very large arrays.
ConversionOne 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 PythonFive 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.