★ Reading this for free? Get 20 structured AI courses + per-chapter AI tutor — the first chapter of every course free, no card.Start free in 30 seconds
Ollama

OLLAMA_MODELS Not Working? Fix It by Platform

August 23, 2026
12 min read
Local AI Master Research Team

Want to go deeper than this article?

Free account unlocks the first chapter of all 25 courses — RAG, agents, MCP, voice AI, MLOps, real GitHub repos.

📚AI Learning Path

Ollama’s running. Here’s what to build with it. Go from “ollama run” to RAG apps, agents, and fine-tuned models — structured and hands-on. First chapter free.

Start free
Or own it for life — Lifetime $149, pay once

Three different mechanisms swallow OLLAMA_MODELS, and which one you have depends on how the server was started. If you use the desktop app, the app overwrites your variable: app/server/server.go copies your environment and then sets env["OLLAMA_MODELS"] = settings.Models from the app's own Model location setting before spawning ollama serve, so the GUI wins - set the GUI path to match. If you run the Linux systemd service, your shell export never reaches the daemon and you need Environment= in a systemd override plus chown -R ollama:ollama on the target. And on every platform, the ollama CLI is a thin HTTP client - setting the variable in the terminal you type ollama list into changes nothing at all.

That last one is worth repeating because it makes the other two invisible. When you export OLLAMA_MODELS=/mnt/big-disk/ollama and then run ollama list, you have configured the client. The client sends an HTTP request to a daemon that was started by launchd, systemd or the desktop app, with a completely different environment. The daemon is the only process whose OLLAMA_MODELS matters.

Below: how to read the path the server is really using, a per-platform truth table, the fix for each failure, and how to move the models you already have without downloading them again.

How do I see which path the server is actually using?

Stop guessing from your shell. The Ollama server prints its entire effective configuration on startup, including the resolved models path, in a log line tagged msg="server config". Every diagnosis on this page starts by reading that line.

How you run OllamaWhere that line is
ollama serve in a terminalPrinted to the terminal immediately
macOS desktop app~/.ollama/logs/server.log
Windows desktop app%LOCALAPPDATA%\Ollama\server.log
Linux systemd servicejournalctl -u ollama --since "10 minutes ago"

Inside that line, find OLLAMA_MODELS:. Here is a real excerpt, from the report in issue #17374, where the user had set the variable to C:\models and the app-started server logged something else entirely:

msg="server config" env="map[... OLLAMA_MODELS:C:\Users\sebastian\.ollama ...]"

while running ollama serve by hand in the same session logged OLLAMA_MODELS:C:\models. Same machine, same user variable, two different answers, because the app supplies its own. That comparison is the fastest diagnostic on this page: run ollama serve manually and compare the two config lines.

One gotcha that is not the problem, despite a lot of advice suggesting it: quoting. envconfig.Var() is documented as returning "an environment variable stripped of leading and trailing quotes or spaces", so OLLAMA_MODELS="D:\models" with literal quotes still resolves correctly.

Reading articles is good. Building is better.

Free account = 20+ free chapters across 25 courses, with a per-chapter AI tutor. No card. Cancel anytime if you ever upgrade.

The per-platform truth table

Different platforms fail differently. Find your row.

Platform / launch methodWhat sets the daemon's environmentThe failure mode you are hittingThe fix
Windows, desktop appThe app's own settings store, which overwrites OLLAMA_MODELS in the child environmentUser env var is set correctly and ignored; ollama list comes back emptySet the app's Model location to the same directory as the variable
Windows, ollama serve by handThe environment of that terminalWorks. This is the comparison case that proves the app is the culpritNothing, but you must keep the app closed
macOS, desktop applaunchd, plus the same app settings storeexport in .zshrc is never read by a launchd-started applaunchctl setenv OLLAMA_MODELS "/Volumes/AI/models", restart the app, and check the app's model-location setting too
Linux, systemd (official installer)The systemd unit onlyShell exports are invisible to the servicesudo systemctl edit ollama.service, add Environment= under [Service], reload, restart
Linux, systemd, path under /homeSame, but the service runs as the ollama userError: mkdir /home/you: permission denied, service flapsOwnership plus traversal, see the Linux section
DockerThe container's environment, where HOME is /rootSetting the variable on the host does nothing at allChange the volume, not the variable: -v /big/disk:/root/.ollama
Any, set in your shell onlyNothing. The CLI is an HTTP clientThe daemon never sees itSet it wherever the server starts, per the rows above

The default path, when the variable is unset, is not a hardcoded per-OS constant. envconfig.Models() returns OLLAMA_MODELS if set, otherwise filepath.Join(os.UserHomeDir(), ".ollama", "models") - it is always the server process's home directory. That is why the official FAQ documents Linux as /usr/share/ollama/.ollama/models: the installer creates the service account with useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama, so /usr/share/ollama is the home directory for the daemon. Same code, different home, different answer.

OSDocumented defaultWhere that path comes from
macOS~/.ollama/modelsYour home directory, because the app runs as you
Linux (official installer)/usr/share/ollama/.ollama/modelsThe ollama service account's home, set by install.sh
WindowsC:\Users\%username%\.ollama\modelsYour home directory
Docker (official run command)/root/.ollama/modelsHOME inside the container is /root; the documented command mounts -v ollama:/root/.ollama

Windows: why the desktop app overrides your variable

This is the single most common cause on Windows, and it is not a mistake in your setup. The desktop app does not merely fail to read your variable - it actively replaces it. From app/server/server.go, in the function that builds the ollama serve child process:

// Copy and mutate the environment to merge in settings the user has specified without dups
env := map[string]string{}
for _, kv := range os.Environ() {
    s := strings.SplitN(kv, "=", 2)
    env[s[0]] = s[1]
}
...
if settings.Models != "" {
    if _, err := os.Stat(settings.Models); err == nil {
        env["OLLAMA_MODELS"] = settings.Models
    } else {
        slog.Warn("models path not accessible, using default", "path", settings.Models, "err", err)
    }
}

Your environment is copied in, then the stored setting is written over the top. The app's settings UI calls that field Model location, described in the component source as "Location where models are stored."

The fix, and its two variants

  1. Match the paths. Open the app's settings and point Model location at the same directory as your OLLAMA_MODELS variable. This is exactly the resolution the reporter of issue #17867 confirmed: "Setting Settings -> Model location to the same directory as OLLAMA_MODELS resolved the issue, including after restarting Ollama."
  2. Or bypass the app. Quit Ollama from the tray and run ollama serve in a terminal that has the variable set. The reporter of issue #17374 used exactly this to prove where the override came from.

PR #17401, "app: honor OLLAMA_MODELS over desktop settings path", would invert the precedence, show the effective path in Settings, and disable the Browse button while the variable is in control. It was open and unmerged at the time of writing, so on a current build the GUI still wins. Check its status before assuming your version behaves differently.

The silent-fallback trap

Look at that else branch again. If the stored path fails os.Stat - an unplugged external drive, an unmounted network share, a drive letter that moved - the app drops the setting entirely and starts the server on your home directory instead, logging only models path not accessible, using default at WARN level. The visible symptom is not an error. It is an empty ollama list, or a prompt to re-download models you know you already have. If your models vanished after a reboot, check whether the drive mounted before you check anything else.

The rest of the Windows-specific install surface - per-user installer, custom program directory, the standalone CLI zip - is covered in our Ollama on Windows installation guide.

macOS: does launchctl setenv still work?

Yes, and it is still the documented method, but on a Mac you have to consider the same desktop-app override as Windows, because the app's server-spawning code is shared across platforms.

The FAQ's instruction is unchanged: "If Ollama is run as a macOS application, environment variables should be set using launchctl."

launchctl setenv OLLAMA_MODELS "/Volumes/AI/ollama-models"

Then quit and relaunch the Ollama application. Two things people get wrong here:

  • .zshrc and .zprofile do nothing. A launchd-started app never sources your shell startup files. This is the substance of issue #4749, where the reporter set the variable in .zshrc and found it applied only when they launched Ollama from a Terminal.
  • launchctl setenv does not survive a reboot on its own. It sets the variable in the current user session's launchd context. If your models directory reverts after restarting the Mac, that is why - re-run it, or install a LaunchAgent that sets it at login.

Because settings.Models is applied in the shared cmd() path rather than in Windows-only code, the app-settings override applies wherever the desktop app spawns the server. Every report on the tracker so far is from Windows users, so treat this as "check it, then rule it out": start the app, read ~/.ollama/logs/server.log, and see which path the server config line contains.

If launchctl genuinely will not stick, the workaround suggested in the #4749 thread is a symlink, which sidesteps the variable entirely:

# with Ollama quit, and the models already moved
ln -s /Volumes/AI/ollama-models ~/.ollama/models

That is a legitimate fallback rather than a hack, because Ollama only ever resolves a path. The caveat is external volumes: if the drive is not mounted at login the symlink dangles, and you are back to an empty model list.

Reading articles is good. Building is better.

Free account = 20+ free chapters across 25 courses, with a per-chapter AI tutor. No card. Cancel anytime if you ever upgrade.

Linux: Environment=, ownership, and mkdir permission denied

Two separate things go wrong on Linux, and they produce different symptoms.

1. The service never sees your variable

The systemd unit is the only environment the daemon has. The documented method:

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_MODELS=/mnt/ssd/ollama/models"
sudo systemctl daemon-reload
sudo systemctl restart ollama

Confirm it took with systemctl show ollama -p Environment, then confirm the server agrees by checking the server config line in journalctl -u ollama. Those are two different checks and both are worth doing: the first proves systemd parsed your override, the second proves Ollama used it.

2. Permission denied, and the service flaps

The second failure is louder. From issue #2701, still open:

ollama[37688]: Error: mkdir /home/crystal: permission denied
systemd[1]: ollama.service: Main process exited, code=exited, status=1/FAILURE

and the near-identical issue #2147:

sh[301002]: Error: mkdir /home/lasse/model_drive: permission denied

The reporter of #2147 had already set the target directory to drwxrwxrwx, which is the detail that makes this confusing. Three causes, in the order to check them:

  1. Ownership of the directory itself. The FAQ is explicit: "On Linux using the standard installer, the ollama user needs read and write access to the specified directory. To assign the directory to the ollama user run sudo chown -R ollama:ollama <directory>."
  2. Traversal of every parent. A world-writable folder is unreachable if a parent is not world-executable. On most distributions /home/you is 0750 or 0700, so the ollama service account cannot enter it no matter how open the target is. Check with sudo -u ollama ls /path/to/models - if that fails, the mode on a parent is the problem, not the target.
  3. Systemd sandboxing. The unit pasted into #2701 contains ProtectHome=yes and ProtectSystem=full. ProtectHome=yes makes /home inaccessible to the service regardless of file permissions, which is why chmod appears to do nothing. The unit written by Ollama's own install.sh does not set those directives, but several distribution packages do - read your actual unit with systemctl cat ollama before blaming permissions.

The cleanest answer to all three is to stop fighting /home: put the models somewhere the service account can own outright, such as /mnt/ssd/ollama/models or /var/lib/ollama/models, then chown -R ollama:ollama it. Broader Linux setup is covered in our Linux local AI setup guide.

How do I move models I already have without re-downloading?

Move two directories, not one. A model is a set of content-addressed blobs plus a manifest that gives them a name. Copy blobs/ without manifests/ and ollama list is empty even though the weights are all there.

# 1. stop the server first - never move files under a running daemon
sudo systemctl stop ollama          # or quit the app from the tray / menu bar

# 2. move both directories, preserving structure
sudo mkdir -p /mnt/ssd/ollama/models
sudo rsync -a /usr/share/ollama/.ollama/models/ /mnt/ssd/ollama/models/

# 3. Linux only: hand the whole tree to the service account
sudo chown -R ollama:ollama /mnt/ssd/ollama/models

# 4. point the *server* at it, restart it, then verify
ollama list

Use rsync -a (or robocopy /E /COPYALL on Windows) rather than a drag-and-drop, so nothing is silently skipped. Verify ollama list returns the full set before you delete the original: the old directory is your only backup, and re-downloading is precisely what you are trying to avoid.

Moving to a machine that has no internet at all is a related but different job. The copy Ollama models to an offline PC guide covers checksums, the standalone CLI archive, and the no-installer path. If the reason you are moving models is that a download keeps dying, read why ollama pull gets stuck or crawls first - a partial download you can resume is cheaper than a migration.

Why is ollama list empty after I moved everything?

Work down this list. It is ordered by how often each turns out to be the answer.

CheckHow to test itWhat it means
The daemon is using a different path than you thinkRead OLLAMA_MODELS in the server config log lineThe variable never reached the server, go back to the truth table
The desktop app overrode itCompare that line against a manual ollama serveMatch the app's Model location to the variable
You copied blobs/ but not manifests/ls both inside the new directoryNo manifest means no name, so nothing lists
Wrong nesting levelYou should see blobs/ and manifests/ directly inside the pathAn extra models/ layer is the usual slip
Permissionssudo -u ollama ls <path>/manifestsThe service account cannot read what you copied
The drive was not mounted at startLook for the WARN line models path not accessible, using defaultThe app silently fell back to your home directory
You never restarted the serversystemctl restart ollama, or quit and relaunch the appThe path is read at startup, not per request

If everything checks out and models still do not appear, the Ollama troubleshooting guide has the wider environment-variable reference, and the complete Ollama guide covers the normal install and storage layout.

Honest limitations

  • This is a code and tracker reading, not a lab report. The behaviour above comes from ollama/ollama on main and from users' own logs in the linked issues. We do not have every platform combination on a bench and are not going to pretend otherwise.
  • The desktop-app override is under active change. PR #17401 was open and unmerged when this was written, and issue #17867 was closed. If your build post-dates a merge, the precedence may have flipped in your favour, and the server config line will tell you in five seconds.
  • The macOS desktop-app override is inferred from shared code, not from a reproduction: cmd() in app/server/server.go is platform-independent, but every report on the tracker so far is from Windows. Verify on your own machine before treating it as established.
  • Distribution packages differ from the official installer. ProtectHome, service account names and default paths are all things a distro maintainer can change. systemctl cat ollama beats any article, including this one.
  • We have not tested every filesystem. Network shares, exFAT drives and cloud-synced folders introduce their own permission and locking behaviour on top of everything above. A local, natively-formatted disk is the boring choice that works.

FAQ

Why does Ollama ignore OLLAMA_MODELS on Windows?

Almost always because the desktop app supplies its own value. app/server/server.go copies your environment and then overwrites OLLAMA_MODELS with the path stored in the app's Model location setting before it starts the server. Set that field to the same directory as your variable, or quit the app and run ollama serve yourself. Issue #17867 confirms that matching the two paths resolves it.

Do I need to set OLLAMA_MODELS in my shell as well?

No, and doing so is what hides the real problem. The ollama command is a thin HTTP client that asks the running daemon; the daemon's environment is the only one that counts. Set the variable wherever the server is launched: the systemd unit on Linux, launchctl setenv on macOS, the user environment plus the app's settings on Windows.

Where does Ollama store models by default?

macOS ~/.ollama/models, Linux /usr/share/ollama/.ollama/models, Windows C:\Users\%username%\.ollama\models. None of these are hardcoded: envconfig.Models() falls back to .ollama/models inside the home directory of whichever account runs the server, and Linux looks different only because the installer gives the ollama service account a home of /usr/share/ollama.

Why do I get "mkdir ...: permission denied" when the folder is already 777?

Because the mode on the target is not the whole story. The ollama service account also needs execute permission on every parent directory, and /home/you is typically 0700. If your unit sets ProtectHome=yes, systemd blocks /home outright no matter what the permissions say. Run systemctl cat ollama to see the real unit, and prefer a path like /mnt/ssd/ollama/models that the service can own.

Yes, and on macOS it is a reasonable fallback when launchctl setenv will not stick across reboots. Quit Ollama, move the directory, then link the old path to the new one. The caveat is external drives: if the volume is not mounted when the server starts, the symlink dangles and Ollama behaves as though you have no models at all.

Does OLLAMA_MODELS work inside Docker?

Not in the way people expect. Inside the container the home directory is /root, so models land in /root/.ollama/models, and the documented run command mounts a volume there with -v ollama:/root/.ollama. To store models elsewhere, change the bind mount to point at your disk rather than setting a variable on the host, because a host-side variable is never seen by the containerised server.

My models disappeared after a reboot. What happened?

Check whether the drive mounted. If the desktop app's stored model location fails a stat at startup, the code drops the setting and starts the server on the default home directory instead, logging only models path not accessible, using default at WARN level. Nothing is deleted; the server is simply looking in the wrong place, and it will offer to download models you already own.

Sources

  • Ollama FAQ - default model paths per OS, OLLAMA_MODELS, the chown -R ollama:ollama instruction, and the launchctl / systemctl edit / Windows environment-variable procedures
  • Ollama Windows documentation - "Changing Model Location", and the note that the uninstaller will not remove models from a relocated directory
  • ollama/ollama, app/server/server.go - the desktop app's environment merge and settings.Models override
  • ollama/ollama, envconfig/config.go - Models() resolution order and Var() quote stripping
  • ollama/ollama, scripts/install.sh - the systemd unit and the useradd -m -d /usr/share/ollama ollama service account
  • Issues and PRs: #17374 (Windows app ignores the variable, open), #17867 (matching the GUI path fixes it, closed), #17401 (proposed precedence fix, open), #2701 (systemd cannot create the folder, open), #2147 (permission denied in the service file), #4749 (macOS .zshrc versus launchctl)
🎯
AI Learning Path

Ollama’s running. Here’s what to build with it.

Go from “ollama run” to RAG apps, agents, and fine-tuned models — structured and hands-on. First chapter free.

Or own it for life — Lifetime $149 $599, pay once
Once your hardware is sorted

Stop piecing Ollama together from blog posts

Ollama Mastery is 15 chapters end to end — install, model choice, Modelfiles, GPU offload, the API, and the 20 errors that actually happen. Plus 24 more courses.

$149 once unlocks everything, forever — about $0.27/chapter for life. Prefer to spread it out? Pro is $79/year (saves 27%) or $8.99/month.
Secure checkout by Lemon Squeezy — your card never touches this siteInstant access the moment you payFirst chapter of every course is free — try before you buy

Liked this? 20 full AI courses are waiting.

From fundamentals to RAG, agents, MCP servers, voice AI, and production deployment with real GitHub repos. First chapter free, every course.

Reading now
Join the discussion

Local AI Master Research Team

Creator of Local AI Master. I've built datasets with over 77,000 examples and trained AI models from scratch. Now I help people achieve AI independence through local AI mastery.

Build Real AI on Your Machine

RAG, agents, NLP, vision, and MLOps - chapters across 25 courses that take you from reading about AI to building AI.

Want structured AI education?

25 courses, 519+ chapters, from $9. Understand AI, don't just use it.

AI Learning Path
More on Ollama
See the full Best Ollama Models 2026 guide.

Comments (0)

No comments yet. Be the first to share your thoughts!

📅 Published: August 23, 2026🔄 Last Updated: August 23, 2026✓ Manually Reviewed

Ready to Go Beyond Tutorials?

20 structured courses with hands-on chapters - build RAG chatbots, AI agents, and ML pipelines on your own hardware.

🎯
AI Learning Path

Go from reading about AI to building with AI

20 structured courses. Hands-on projects. Runs on your machine. Start free.

Or own it for life — Lifetime $149 $599, pay once

Was this helpful?

LM

Written by the Local AI Master Team

The team behind Local AI Master

We build Local AI Master around practical, testable local AI workflows: model selection, hardware planning, RAG systems, agents, and MLOps. The goal is to turn scattered tutorials into a structured learning path you can follow on your own hardware.

✓ Local AI Curriculum✓ Hands-On Projects✓ Open Source Contributor
📚
Free · no account required

Grab the AI Starter Kit — career roadmap, cheat sheet, setup guide

No spam. Unsubscribe with one click.

🎯
AI Learning Path

Ollama’s running. Here’s what to build with it.

Go from “ollama run” to RAG apps, agents, and fine-tuned models — structured and hands-on. First chapter free.

Or own it for life — Lifetime $149 $599, pay once
Free Tools & Calculators