On this page

On this page

Providers

Ollama troubleshooting

Troubleshooting

WSL2 crash loop (repeated reboots)

On WSL2 with NVIDIA/CUDA, the official Ollama Linux installer creates an ollama.service systemd unit with Restart=always. If that service autostarts and loads a GPU-backed model during WSL2 boot, Ollama can pin host memory while loading; Hyper-V memory reclaim cannot always reclaim those pages, so Windows can terminate the WSL2 VM, systemd restarts Ollama, and the loop repeats.

Evidence: repeated WSL2 reboots/terminations, high CPU in app.slice or ollama.service right after WSL2 startup, and SIGTERM from systemd rather than the Linux OOM killer.

OpenClaw logs a startup warning when it detects WSL2, ollama.service enabled with Restart=always, and visible CUDA markers.

Mitigation:

bash
sudo systemctl disable ollama

On the Windows side, add this to %USERPROFILE%\.wslconfig, then run wsl --shutdown:

ini
[experimental]autoMemoryReclaim=disabled

Or shorten keep-alive / start Ollama manually only when needed:

bash
export OLLAMA_KEEP_ALIVE=5mollama serve

See ollama/ollama#11317.

Ollama not detected

Confirm Ollama is running and is in the agent's model scope. For ambient localhost discovery, set OLLAMA_API_KEY (or an auth profile). An explicit self-hosted endpoint is discovered whether or not it lists models:

bash
ollama servecurl http://localhost:11434/api/tags
No models available

Pull the model locally, or define it explicitly in models.providers.ollama:

bash
ollama list  # See what's installedollama pull gemma4ollama pull gpt-oss:20bollama pull llama3.3     # Or another model
Connection refused
bash
# Check if Ollama is runningps aux | grep ollama # Or restart Ollamaollama serve
Remote host works with curl but not OpenClaw

Verify from the same machine and runtime that runs the Gateway:

bash
openclaw gateway status --deepcurl http://ollama-host:11434/api/tags

Common causes:

  • baseUrl points at localhost, but the Gateway runs in Docker or on another host.
  • The URL uses /v1, selecting OpenAI-compatible behavior instead of native Ollama.
  • The remote host needs firewall or LAN binding changes.
  • The model is on your laptop's daemon but not the remote one.
Model outputs tool calls as text

Usually the provider is in OpenAI-compatible mode, or the model cannot handle tool schemas. Prefer native mode:

json5
{  models: {    providers: {      ollama: {        baseUrl: "http://ollama-host:11434",        api: "ollama",      },    },  },}

If a small local model still fails on tool schemas, set compat.supportsTools: false on that model entry and retest.

When a reply consists of a structured tool-call attempt naming an available tool, including wrapped XML, ReAct Action/Action Input, and legacy [TOOL_CALL] blocks, OpenClaw asks the model once to call the tool natively when recovery is safe. Earlier side effects can prevent that retry. A repeated text call fails visibly instead of reporting success. Text calls are never executed by this guard; examples in substantive answers remain text. The original reply and corrective continuation remain in session history.

Repeated tool errors stop the turn

With tools.toolSearch unset, embedded runs using native local Ollama expose policy-approved web_search, web_fetch, memory_search, and memory_get directly. Other optional tools remain deferred. Explicit Tool Search settings keep their configured behavior. Direct exposure does not enable a denied tool, enable memory, or configure a web-search provider.

OpenClaw stops after three consecutive identical failures for the same tool and arguments, including repeated unknown tool IDs. This protection is always active; enabling tools.loopDetection is not required.

Ollama 0.40's generic parser can mistake a chat-template marker for an advertised tool name. Tool Search uses the collision-free dispatch_action name across providers, with the same name in instructions, requests, and new session history. It no longer needs an openclaw_tool_call wire alias. Directly exposed names that still collide, such as ls, name, and function, retain transport-only aliases such as openclaw_ls. Execution and session history keep those tools' original names.

These remaining aliases cover native Ollama and the Ollama plugin's identified OpenAI-compatible chat-completions route. Other providers are unchanged. Custom Ollama templates with different markers may need separate diagnosis.

Check the arguments in the recorded error. If the model repeatedly invents tool names or cannot use the exposed schemas, switch to a model with native tool calling and start a new turn. Changed errors and successful retries reset the count. See Tool-loop detection.

Repetitive output stopped

OpenClaw stopped a long repetition-dominated response from a model with a known total size in the 32B class or smaller. It replaced the affected unfinished block in session history with [Repetitive output stopped]. Earlier blocks and completed tool work remain; side effects are not retried automatically.

Try a stronger model, request less output, or split the task into smaller turns. Native Ollama requests also send the resolved model output cap as num_predict; lower the model's maxTokens if generation runs too long. Discovered local models default to 8,192 output tokens. Ollama Cloud models use their documented output limits, or their context window when a separate output limit is unavailable. Authored maxTokens and params.num_predict override those defaults. Set params: { num_predict: -1 } on a model entry to restore Ollama's unlimited generation default; an explicit request output cap still wins. The detector starts around 16,000 characters and can stop legitimate output with sufficiently dominant repetition. It applies to the 32B class (less than 34 billion total parameters) and stays off when total model size is unknown. See Output budgets and repetition stops.

Kimi or GLM returns garbled symbols

Hosted Kimi/GLM responses that are long, non-linguistic symbol runs are treated as a failed provider call rather than a successful reply, so normal retry/fallback/error handling takes over instead of persisting corrupted text into the session.

If it recurs, capture the model name, the current session file, and whether the run used Cloud + Local or Ollama Cloud, then try a fresh session and a fallback model:

bash
openclaw infer model run --model ollama/kimi-k2.6:cloud --prompt "Reply with exactly: ok" --jsonopenclaw models set ollama/gemma4
Cold local model times out

Large local models can need a long first load. Scope the timeout to the Ollama provider and optionally keep the model loaded between turns:

json5
{  models: {    providers: {      ollama: {        timeoutSeconds: 300,        models: [          {            id: "gemma4:26b",            name: "gemma4:26b",            params: { keep_alive: "15m" },          },        ],      },    },  },}

If the host itself is slow to accept connections, timeoutSeconds also extends the guarded connect timeout for this provider.

Large-context model is too slow or runs out of memory

Many models advertise contexts larger than your hardware can run comfortably. Native requests forward the effective contextTokens unless params.num_ctx overrides it. Cap both OpenClaw's budget and Ollama's request context for predictable first-token latency:

json5
{  models: {    providers: {      ollama: {        maxTokens: 8192,        models: [          {            id: "qwen3.5:9b",            name: "qwen3.5:9b",            contextTokens: 32768,            params: { num_ctx: 32768, thinking: false },          },        ],      },    },  },}

Lower the model entry's contextTokens if OpenClaw sends too much prompt. Lower params.num_ctx if Ollama's runtime context is too large for the machine. Lower maxTokens if generation runs too long.

Memory embedding rebuild fails

If openclaw memory index --force fails against Ollama (for example with bge-m3), try llmman as the embedding server. provider: "ollama" only needs a new remote.baseUrl.

Ollama still aborts or hangs on this host

If curl to Ollama works but agent turns abort, try llmman as the local server.

Was this useful?