HTTP/1.1 403 Forbidden with an empty body from Ollama, for a request that carries an
Origin header, means the web page's origin is not on Ollama's allow list. Add that origin to
the OLLAMA_ORIGINS environment variable and restart the Ollama server; nothing else about the
request is wrong.
The value must match scheme, host and port exactly. List several with commas, and write
http://app.example.test:* to allow every port of one host.
The error
PS> curl.exe -s -i http://127.0.0.1:15101/api/tags -H "Origin: http://app.example.test"
HTTP/1.1 403 Forbidden
Date: Fri, 30 Oct 2026 02:59:38 GMT
Content-Length: 0
PS> curl.exe -s -i -X OPTIONS http://127.0.0.1:15101/api/chat -H "Origin: http://app.example.test" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: content-type"
HTTP/1.1 403 Forbidden
Allow: POST
Date: Fri, 30 Oct 2026 02:59:38 GMT
Content-Length: 0
Why it happens
A browser adds an Origin header to every request a page makes to another origin, and before
a POST with a JSON body it first sends an OPTIONS preflight like the second one above. Ollama
compares the header with its list and answers 403 when it does not match. A request with no
Origin at all, from curl, a backend service or the CLI, is not checked, which is why the same
call works in a terminal and fails in the page. The 403 carries no
Access-Control-Allow-Origin header, so the page's script cannot read anything back.
Ollama's FAQ says: "Ollama allows cross-origin requests from 127.0.0.1 and
0.0.0.0 by default." (docs.ollama.com/faq, re-read
on Oct 30, 2026). The server's own config line was broader: localhost, 127.0.0.1
and 0.0.0.0 over http and https on any port, plus the app://,
file://, tauri:// and two VS Code schemes. That is why a dev server on
http://localhost:5173 worked in the same test while http://app.example.test did not.
The fix
PS> $env:OLLAMA_ORIGINS = "http://app.example.test"
PS> Select-String -Path .\serve-e.err.txt -Pattern 'OLLAMA_ORIGINS:\[[^\]]*\]' | Select-Object -First 1 | ForEach-Object { $_.Matches[0].Value }
OLLAMA_ORIGINS:[http://app.example.test http://localhost https://localhost ...]
PS> curl.exe -s -i -X OPTIONS http://127.0.0.1:15101/api/chat -H "Origin: http://app.example.test" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: content-type"
HTTP/1.1 204 No Content
Access-Control-Allow-Methods: GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS
Access-Control-Allow-Origin: http://app.example.test
Access-Control-Max-Age: 43200
PS> curl.exe -s -i http://127.0.0.1:15101/api/chat -H "Origin: http://app.example.test" -H "Content-Type: application/json" -d "@chat-ok.json"
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://app.example.test
Between the first two lines the test started ollama serve in the background from the same
session, and the server's config line then showed the new list. Your origin is added in front of the
defaults, it does not replace them. With only
http://app.example.test listed, https://app.example.test and
http://app.example.test:8080 still got 403; adding http://app.example.test:* and
the https form fixed both. OLLAMA_ORIGINS="*" also worked, answering
Access-Control-Allow-Origin: * for a made-up site, which means any web page you open could
call your local models; list real origins instead.
For the installed app, the FAQ's Windows steps are: quit Ollama from the taskbar, add the variable for
your account under "environment variables", and start Ollama again from the Start menu; on Linux, add an
Environment= line with systemctl edit ollama.service, reload systemd and restart
the service. To
confirm what the running app uses, search its log the same way:
Select-String on $env:LOCALAPPDATA\Ollama\server.log printed the default list
here.
How it was reproduced
On Windows 11 with Ollama 0.40.11 and curl.exe 8.21.0 in Windows PowerShell 5.1, against a
separate ollama serve on 127.0.0.1:15101, started four times from PowerShell:
with no OLLAMA_ORIGINS, with one origin, with three, and with *. That port is the
test's own; the installed app was only read, never reconfigured. app.example.test is a
made-up host sent only as a header, so no browser or web page was involved.
Frequently asked
- How do I fix Ollama CORS errors in the browser?
- Add the page's origin, scheme, host and port, to the OLLAMA_ORIGINS environment variable and restart Ollama. Separate several values with commas; host:* allows every port of that host, and the https form must be listed separately.
- Which origins does Ollama allow by default?
- In version 0.40.11 the server's config line listed localhost, 127.0.0.1 and 0.0.0.0 over http and https on any port, plus the app, file, tauri and two VS Code schemes. Anything else gets 403 Forbidden.
- Why does curl work but my web page gets 403 from Ollama?
- curl sends no Origin header unless you add one, and Ollama only checks requests that carry it. A browser sends it for every request a page makes to another origin, so the page is refused while curl is not.
More decoded errors in the Fixes category. If the page talks to your own ASP.NET Core API instead, the same browser rule has its own post: 'No Access-Control-Allow-Origin header' in ASP.NET Core.