Skip to content

MLX: No Metal Device Available

8 min read · updated August 11, 2026

MLX will not run on a CPU. When it cannot find a Metal device it stops, and the message is unusually forthcoming about why — it names the situations that cause it.

The string

The runtime error, thrown from MLX’s Metal device setup:

RuntimeError: [metal::load_device] No Metal device available. This typically occurs in headless, sandboxed, or virtualized macOS sessions where the GPU is not accessible.

That wording is quoted from MLX’s own source, and the three words in it — headless, sandboxed, virtualized — are the diagnosis. A second, different Metal error is much more common in practice and is often confused with this one:

RuntimeError: Failed to load the default metallib.

Those are not the same failure. The first means no GPU was found at all. The second means a GPU was found and MLX could not locate its own compiled shader library. They have unrelated fixes, and the last section covers the second.

Why there is no CPU fallback

MLX is built for Apple silicon’s unified memory architecture: arrays live in memory that both CPU and GPU address, so there is no host-to-device copy and no separate device pointer. The GPU backend is not an accelerator bolted onto a portable implementation — it is the implementation. There is nothing to fall back to, and the framework raises rather than silently degrading.

This is the opposite convention from PyTorch, where a missing CUDA build gives you a working CPU tensor library and an error only when you call .cuda() — the situation behind Torch not compiled with CUDA enabled. Expecting MLX to behave that way is what makes this error surprising.

The four requirements, checked

MLX’s installation documentation states four conditions, and every one of them produces a failure at import or at first use if unmet. Check them in this order, because each is cheaper than the next.

  1. An M-series chip. MLX requires Apple silicon. There is no Intel Mac path, with or without an external GPU. If uname -m reports x86_64 on hardware you know is M-series, skip to step two; if the hardware is genuinely Intel, MLX is not the tool and llama.cpp with a Metal or CPU backend is.
  2. A native arm Python, not one under Rosetta. This is the most common cause among people on correct hardware, and it is invisible until you look. MLX documents the check:
    python -c "import platform; print(platform.processor())"
    # expected: arm    (i386 means you are under Rosetta)
    
    uname -p
    # expected: arm
    An x86 Homebrew, an old Conda environment, or a terminal launched with “Open using Rosetta” ticked will all give you an x86_64 interpreter on an M-series machine. The fix is a native interpreter in a fresh environment, not a reinstall of MLX into the translated one. Note that a Rosetta environment usually fails at pip install before it ever reaches this error, because no matching wheel exists.
  3. macOS at or above MLX’s floor, documented as macOS 14.0 or newer at the time of writing. Below that, the Metal features MLX compiles against are not present.
  4. Python 3.10 or newer, also from the install documentation. An older interpreter fails at install rather than at runtime, but it belongs on the same checklist.
The macOS floor and the Python floor both move as MLX develops. Confirm them against MLX’s current installation documentation rather than against a version number quoted in a thread.

Headless, SSH, containers and VMs

If the four requirements hold and you still get the error, you are in one of the three situations the message names, and the common thread is that the process has no access to a window server session.

  • SSH into a Mac with no console session. A Mac that has rebooted and not been logged in at the screen may not have the graphics stack available to a remote shell. Logging in at the console once — or enabling automatic login, or connecting via screen sharing to establish a session — is the practical fix.
  • A launch daemon or CI agent. Processes started by launchd as system daemons run outside a user session by design. Running the same work as a user agent, in a logged-in session, is what gives it a GPU.
  • A virtualised macOS guest. GPU passthrough to macOS VMs is limited and depends on the host virtualisation stack. A guest without accelerated graphics has no Metal device, and no configuration inside the guest creates one.
  • Sandboxed or containerised execution. A sandbox that withholds GPU entitlements produces the same result. Linux containers cannot help at all — MLX is macOS-only, so a Docker image on any host is not a route to running it.

For what the hardware can do once MLX does start, see running models on Apple silicon.

The other Metal error, which is packaging

Failed to load the default metallib is a different problem with the same aesthetics. MLX ships precompiled Metal shaders in a .metallib and looks for it in known locations relative to the loaded framework. The error means the GPU is fine and the file was not where MLX looked. Reported origins cluster around:

  • An application bundle built by a packaging tool that dropped the resource bundle for an external dependency. This has repeatedly hit downstream apps that embed MLX and is fixed in the app, not by the user.
  • A source build where the Metal toolchain was installed after MLX, or a stale build directory. Removing the build directory and rebuilding is the documented recovery.
  • A framework-style installation where the library sits in a Resources directory that older MLX did not search.

Distinguish them by the wording alone: “No Metal device available” is an environment problem you fix by giving the process a GPU session; “Failed to load the default metallib” is a packaging problem you fix by reinstalling or rebuilding. Two other MLX failures worth knowing while you are here are the shell reporting the process as killed and parameters that are not in the model.