litellm - ✅(Solved) Fix [Bug] Ollama provider checks `litellm.api_base` global before explicit `api_base` kwarg (inconsistent with openai provider) [2 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
BerriAI/litellm#26170Fetched 2026-04-22 07:46:02
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×2labeled ×1

In litellm/main.py, the three Ollama-related provider blocks resolve api_base with the global litellm.api_base before the explicit api_base kwarg, while the openai provider (and every other major provider) resolve in the opposite order. This causes the explicit kwarg passed to litellm.completion(...) or litellm.embedding(...) to be silently overridden when litellm.api_base has been set by unrelated code earlier in the process.

Error Message

import litellm

simulate an earlier openai-compat provider (e.g. DeepSeek, Groq via openai-compat)

setting the global api_base — any downstream code can do this

litellm.api_base = "https://api.deepseek.com"

r = litellm.embedding( model="ollama/qwen3-embedding:0.6b", input="hello", api_base="http://localhost:11434", # explicit kwarg — should win )

litellm.APIConnectionError: OllamaException

Client error '401 Unauthorized' for url 'https://api.deepseek.com/api/embed'

Root Cause

In litellm/main.py, the three Ollama-related provider blocks resolve api_base with the global litellm.api_base before the explicit api_base kwarg, while the openai provider (and every other major provider) resolve in the opposite order. This causes the explicit kwarg passed to litellm.completion(...) or litellm.embedding(...) to be silently overridden when litellm.api_base has been set by unrelated code earlier in the process.

Fix Action

Fixed

PR fix notes

PR #26171: Fix: ollama provider respects explicit api_base kwarg over global

Description (problem / solution / changelog)

Fixes #26170.

What

The ollama, ollama_chat, and ollama embedding provider blocks in litellm/main.py resolved api_base as litellm.api_base or api_base or ... — global first, explicit kwarg second. This contradicts the openai provider (line 2038) and every other major provider block in the same file, which resolve kwarg first.

Swap the first two operands in each of the three blocks so the explicit kwarg wins. Behavior is now consistent with the openai provider.

Impact

Client code that explicitly passes api_base="http://my-ollama:11434" to litellm.completion() or litellm.embedding() had the value silently overridden if litellm.api_base happened to be set globally by unrelated code. This happens in practice whenever an application routes multiple providers through LiteLLM — e.g. an openai-compat provider like DeepSeek sets litellm.api_base = "https://api.deepseek.com" during its own init, and subsequent ollama calls inherit the wrong URL.

Real-world repro and symptom are in #26170.

Change

Three two-line swaps. No new logic, no semantic change to the other resolution fallbacks (get_secret("OLLAMA_API_BASE") and the localhost default remain the final fallbacks).

LineProvider
3970ollama (completion path)
3999ollama_chat (completion path)
5318ollama (embedding path)

Manual verification

With the patch applied locally:

import litellm
litellm.api_base = "https://api.deepseek.com"   # simulate leaked global

r = litellm.embedding(
    model="ollama/qwen3-embedding:0.6b",
    input="hello",
    api_base="http://ollama:11434",
)
# ✓ hits http://ollama:11434/api/embed, returns embedding

Before the patch, the same call 401s at api.deepseek.com.

Changed files

  • litellm/main.py (modified, +6/-6)

PR #26177: fix(ollama): prefer explicit api_base

Description (problem / solution / changelog)

Summary

  • make the explicit api_base kwarg win over the global litellm.api_base for ollama completion
  • apply the same precedence fix to ollama_chat completion and ollama embeddings
  • add regression tests for completion and embedding paths

Closes #26170.

Testing

  • attempted: python3 -m pytest tests/local_testing/test_completion.py -q -k "ollama_completion_explicit_api_base_takes_precedence or ollama_embedding_explicit_api_base_takes_precedence"
  • blocked locally because litellm imports tiktoken during test setup and tiktoken is not installed in the current environment

Changed files

  • litellm/main.py (modified, +6/-6)
  • tests/local_testing/test_completion.py (modified, +47/-0)

Code Example

api_base = (
    litellm.api_base            # global FIRST ← bug
    or api_base                 # explicit kwarg SECOND
    or get_secret("OLLAMA_API_BASE")
    or "http://localhost:11434"
)

---

api_base = (
    api_base                    # kwarg FIRST
    or litellm.api_base
    or get_secret("OPENAI_BASE_URL")
    or get_secret("OPENAI_API_BASE")
    or "https://api.openai.com/v1"
)

---

import litellm

# simulate an earlier openai-compat provider (e.g. DeepSeek, Groq via openai-compat)
# setting the global api_base — any downstream code can do this
litellm.api_base = "https://api.deepseek.com"

r = litellm.embedding(
    model="ollama/qwen3-embedding:0.6b",
    input="hello",
    api_base="http://localhost:11434",  # explicit kwarg — should win
)
# litellm.APIConnectionError: OllamaException
# Client error '401 Unauthorized' for url 'https://api.deepseek.com/api/embed'
RAW_BUFFERClick to expand / collapse

Description

In litellm/main.py, the three Ollama-related provider blocks resolve api_base with the global litellm.api_base before the explicit api_base kwarg, while the openai provider (and every other major provider) resolve in the opposite order. This causes the explicit kwarg passed to litellm.completion(...) or litellm.embedding(...) to be silently overridden when litellm.api_base has been set by unrelated code earlier in the process.

Affected code (current litellm_internal_staging)

  • litellm/main.py:3970 — ollama completion path
  • litellm/main.py:3999 — ollama_chat completion path
  • litellm/main.py:5318 — ollama embedding path

All three currently read:

api_base = (
    litellm.api_base            # global FIRST ← bug
    or api_base                 # explicit kwarg SECOND
    or get_secret("OLLAMA_API_BASE")
    or "http://localhost:11434"
)

Compare with the openai provider at litellm/main.py:2038 and other occurrences — they all resolve kwarg first:

api_base = (
    api_base                    # kwarg FIRST
    or litellm.api_base
    or get_secret("OPENAI_BASE_URL")
    or get_secret("OPENAI_API_BASE")
    or "https://api.openai.com/v1"
)

Reproduction

import litellm

# simulate an earlier openai-compat provider (e.g. DeepSeek, Groq via openai-compat)
# setting the global api_base — any downstream code can do this
litellm.api_base = "https://api.deepseek.com"

r = litellm.embedding(
    model="ollama/qwen3-embedding:0.6b",
    input="hello",
    api_base="http://localhost:11434",  # explicit kwarg — should win
)
# litellm.APIConnectionError: OllamaException
# Client error '401 Unauthorized' for url 'https://api.deepseek.com/api/embed'

Observed in the wild

SurfSense (self-hosted NotebookLM alternative) routes DeepSeek chat via LiteLLM's openai provider with api_base="https://api.deepseek.com"; that call mutates litellm.api_base. Subsequent ollama embedding calls then inherit DeepSeek's URL and 401. Full downstream discussion: https://github.com/aydenious/surfsense/blob/master/docs/gotchas.md#litellm-global-api_base-bug.

Suggested fix

Swap the first two operands in each of the three blocks so the explicit api_base kwarg wins, matching the openai provider's pattern. PR follows.

Environment

  • litellm==1.83.0
  • Bug also present on litellm_internal_staging as of today.

extent analysis

TL;DR

The issue can be fixed by swapping the order of litellm.api_base and api_base in the api_base assignment to prioritize the explicit keyword argument.

Guidance

  • Identify the three affected code blocks in litellm/main.py (lines 3970, 3999, and 5318) and modify the api_base assignment to prioritize the explicit api_base keyword argument.
  • Verify the fix by testing the litellm.embedding function with an explicit api_base keyword argument and checking that it is not overridden by the global litellm.api_base value.
  • Review other providers (e.g., openai) to ensure consistency in api_base resolution order.
  • Consider adding tests to prevent similar issues in the future.

Example

api_base = (
    api_base                 # explicit kwarg FIRST
    or litellm.api_base      # global SECOND
    or get_secret("OLLAMA_API_BASE")
    or "http://localhost:11434"
)

Notes

The suggested fix assumes that the explicit api_base keyword argument should take precedence over the global litellm.api_base value. If this is not the intended behavior, further investigation may be necessary.

Recommendation

Apply the workaround by swapping the order of litellm.api_base and api_base in the affected code blocks, as this will ensure that the explicit keyword argument is prioritized.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

litellm - ✅(Solved) Fix [Bug] Ollama provider checks `litellm.api_base` global before explicit `api_base` kwarg (inconsistent with openai provider) [2 pull requests, 1 participants]