You run ollama pull llama3.2:3b, the progress bar reaches 100%, the last line prints success, and then ollama list doesn’t show the model. ollama run llama3.2:3b returns Error: model 'llama3.2:3b' not found. The blobs are clearly on disk — you can see them under a models/blobs/ directory — so this is not a download failure. The blobs exist but the manifest that tells Ollama what those blobs compose is either missing, corrupt, or sitting in a directory the running Ollama process never reads.
Fastest fix (works ~80% of the time): the CLI and the Ollama daemon are reading two different model directories. Pull and list talk to the same daemon, so the real split is almost always a stale OLLAMA_MODELS value in your shell versus the path the service actually uses. Run ollama show llama3.2:3b — if that also fails while the blobs are on disk, jump to Step 1 and reconcile the two paths.
Where Ollama actually stores models (June 2026)
Get this right first — most “missing model” reports are just the wrong directory. Defaults as of Ollama 0.x in June 2026:
| Platform / install | Default model directory | Runs as |
|---|---|---|
macOS (app or brew) | ~/.ollama/models | your user |
| Linux (official install script, systemd) | /usr/share/ollama/.ollama/models | the ollama service user |
Linux (ollama serve run manually in a shell) | ~/.ollama/models | your user |
| Windows | C:\Users\%username%\.ollama\models | your user |
| Docker | the path mounted to /root/.ollama in the container | container root |
The classic Linux trap: the install script creates a dedicated ollama system user and a systemd service. That service stores models in /usr/share/ollama/.ollama/models, not in your home directory. If you export OLLAMA_MODELS=/somewhere/else in your shell and pull, you pull into your path, but the daemon keeps reading its own path — so ollama list comes back without the new model.
Common causes
Ordered by hit rate, highest first.
1. OLLAMA_MODELS set in your shell but not in the service
You added export OLLAMA_MODELS=/data/ollama to ~/.bashrc or ~/.zshrc. Systemd services do not inherit your login-shell environment, so the daemon ignores it and uses its default (/usr/share/ollama/.ollama/models on Linux). The CLI you run pulls into /data/ollama only if the daemon honors it — and since pull goes through the same daemon, the pull either lands in the daemon’s default or fails to be visible because the directory differs from what you expect.
How to spot it: compare the two values.
echo "$OLLAMA_MODELS" # your shell's value
systemctl show ollama --property=Environment # the service's value (Linux/systemd)
If they differ — or your shell sets it and the service line is empty — that is the root cause.
2. The ollama service user can’t see (or write) your custom directory
If you point OLLAMA_MODELS at a path the ollama user can’t read or write (a directory under your $HOME, a path owned by root, a not-yet-mounted disk), the daemon silently falls back or writes nothing usable. The blobs may land but the manifest never gets written where the daemon looks.
How to spot it:
ls -la /usr/share/ollama/.ollama/models/manifests/ # who owns it?
# and your custom dir, if any:
ls -ld /data/ollama
The directory and its contents must be owned by ollama:ollama for the systemd install.
3. Manifest is missing, zero-byte, or invalid JSON
After an interrupted pull, a daemon restart mid-pull, or a full disk, Ollama can leave the (large) blobs intact while the small manifest file is empty or truncated. ollama list reads manifests first; a zero-byte or malformed manifest means the model is silently skipped.
How to spot it: check the version file for your tag under the daemon’s directory.
# Linux systemd path shown; use ~/.ollama on macOS/Windows
sudo cat /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/llama3.2/3b \
| python3 -m json.tool
If the file is empty, missing, or python3 -m json.tool reports a JSON error, the manifest is the problem.
4. Disk filled up during the last few seconds of the pull
Blobs download in chunks and are mostly written before the small manifest is committed at the end. If the disk fills during that final write, you get complete blobs but a truncated or absent manifest — and success may still flash by.
How to spot it: df -h /usr/share/ollama (or df -h ~/.ollama on macOS/Windows). If usage is near 100%, free space and re-pull.
5. You pulled with sudo (or as a different user) than the running daemon
Running sudo ollama pull ... can route through a daemon (or write to a path) tied to root, leaving models under /root/.ollama/models instead of the service’s /usr/share/ollama/.ollama/models. Then ollama list as your normal user — talking to the systemd daemon — shows nothing.
How to spot it:
sudo ls /root/.ollama/models/manifests/registry.ollama.ai/library/ 2>/dev/null
ls /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/ 2>/dev/null
If the model only appears under /root/.ollama, it was pulled as root.
6. Tag mismatch — you pulled one tag and listed/ran another
ollama pull llama3.2 (no tag) resolves to llama3.2:latest. If you then run ollama run llama3.2:3b, that is a different tag and will report “not found” even though llama3.2:latest is right there. llama3:latest and llama3.3:latest are also entirely different models.
How to spot it: read the exact NAME column in ollama list and match it character-for-character to what you run.
ollama list
# NAME ID SIZE MODIFIED
# llama3.2:latest a80c4f17acd5 2.0 GB ...
Shortest path to fix
Step 1: Confirm which directory the running daemon reads
# What your shell thinks
echo "$OLLAMA_MODELS"
# What the daemon was started with (Linux/systemd)
systemctl show ollama --property=Environment
# Ask the running daemon directly — this list is the source of truth
curl -s http://localhost:11434/api/tags | python3 -m json.tool
# Inspect the daemon's default directory (Linux systemd install)
sudo ls /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/
# macOS / Windows / manual `ollama serve`:
ls ~/.ollama/models/manifests/registry.ollama.ai/library/
/api/tags returns exactly what ollama list shows; if your model is absent there, the daemon genuinely doesn’t see it.
Step 2: Inspect and repair the manifest
# Linux systemd path; swap to ~/.ollama on macOS/Windows
MANIFEST=/usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/llama3.2/3b
sudo ls -la "$MANIFEST"
sudo cat "$MANIFEST" | python3 -m json.tool # valid JSON, or an error?
# If zero-byte / invalid, remove just the manifest and re-pull.
# Ollama re-uses on-disk blobs by checksum and only rewrites the manifest.
sudo rm -f "$MANIFEST"
ollama pull llama3.2:3b
Step 3: Set OLLAMA_MODELS in the systemd unit (Linux), not just the shell
sudo systemctl edit ollama
# In the editor, under [Service], add:
# [Service]
# Environment="OLLAMA_MODELS=/data/ollama"
# The ollama user must own that directory:
sudo chown -R ollama:ollama /data/ollama
sudo systemctl daemon-reload
sudo systemctl restart ollama
# Confirm the daemon now reports the new path
systemctl show ollama --property=Environment
On macOS, set it for the app instead: launchctl setenv OLLAMA_MODELS "/path", then quit and relaunch Ollama. On Windows, set it in System Environment Variables and restart the Ollama app from the tray.
Step 4: Recover models pulled as root or under the wrong user
# Copy from /root into the service directory, then fix ownership
sudo cp -r /root/.ollama/models/manifests/* /usr/share/ollama/.ollama/models/manifests/
sudo cp -r /root/.ollama/models/blobs/* /usr/share/ollama/.ollama/models/blobs/
sudo chown -R ollama:ollama /usr/share/ollama/.ollama/
sudo systemctl restart ollama
ollama list
Step 5: Restart the daemon and wait for it to be ready
Ollama loads its model registry at startup, so any path change needs a restart before ollama list reflects it.
sudo systemctl restart ollama # macOS/Windows: quit and relaunch the app
# Block until the API answers, then list
until curl -s http://localhost:11434/api/version > /dev/null; do sleep 1; done
ollama list
Step 6: Re-pull with the exact tag if the alias is ambiguous
ollama pull llama3.2:3b # explicit tag, no `latest` guessing
ollama list | grep llama3.2 # confirm the exact NAME:TAG is present
ollama run llama3.2:3b "say hello" # run the same tag you listed
How to confirm it’s fixed
ollama list | grep llama3.2 # 1) the tag is present
ollama show llama3.2:3b # 2) manifest resolves (no "not found")
ollama run llama3.2:3b "1+1=" # 3) it actually loads and answers (~"2")
If all three pass, the manifest and blobs are consistent and the daemon is reading the right directory.
Prevention
- Set
OLLAMA_MODELSin one place that the daemon honors — the systemd override on Linux,launchctl setenvon macOS, System Environment Variables on Windows. Don’t rely on a~/.bashrcexport for a systemd service. - On Linux, remember the daemon’s home is
/usr/share/ollama/.ollama/models, not~/.ollama. Any custom dir must be owned byollama:ollama. - Avoid
sudo ollama pullunless your daemon also runs as root; mismatched users are a top cause of “pulled but not listed.” - After any pull, verify immediately:
ollama list | grep <model>(or in CI:ollama list | grep -q "llama3.2:3b" || exit 1). - Leave headroom on the model disk; check
df -hbefore pulling multi-GB models so the final manifest write can’t be truncated. - After upgrading Ollama or the OS, restart the service to clear the in-memory registry.
FAQ
Q: I downloaded a .gguf file directly (not via ollama pull). How do I make it show up in ollama list?
A: Write a one-line Modelfile pointing at the file, then create the model. From the directory holding the file:
echo 'FROM ./model.gguf' > Modelfile
ollama create mymodel -f Modelfile
This usually takes 10–60 seconds and then mymodel:latest appears in ollama list. Note that sharded GGUF files won’t import directly — merge them first.
Q: The blobs are on disk but ollama show <model> says “not found.” Can I recover without re-downloading?
A: Yes, if you have the manifest. Restore the manifest JSON to .../manifests/registry.ollama.ai/library/<model>/<tag> under the daemon’s models directory and restart Ollama. Because Ollama matches blobs by SHA-256, an ollama pull <model>:<tag> will also rebuild the manifest and reuse the existing blobs instead of re-downloading them.
Q: All my models vanished after a reboot or an Ollama upgrade. Why?
A: Almost always the daemon is now reading a different directory than before — an OLLAMA_MODELS change that didn’t carry over, a disk that mounts after the service starts, or a permission flip on /usr/share/ollama. Check systemctl show ollama --property=Environment and confirm the model directory is owned by ollama:ollama. The blobs are usually still there; you just need the daemon pointed back at them.
Q: How do I move my whole model library to another machine?
A: Copy the entire models/ directory — both blobs/ and manifests/ — to the corresponding path on the target. Set OLLAMA_MODELS there if you use a non-default path, fix ownership (ollama:ollama on a systemd install), then restart the service and run ollama list. The manifest-to-blob structure must stay intact.
Q: The pull hit 100%, reset, and climbed again before finishing — is that a bug?
A: No. ollama pull has a download phase and a verify-plus-write-manifest phase; the bar can reset between them. As long as the last line says success and ollama list shows the tag, it completed normally.