Tencent/WeKnora · error

ollama API returned status %d: %s

Error message

ollama API returned status %d: %s

What it means

This error is returned by the Ollama web-search provider when the Ollama search API responds with an HTTP status other than 200. The provider wraps the actual status code and the raw response body into the error message so the caller can see exactly what Ollama returned. It is a surface for upstream API failures (auth, rate limits, bad endpoints, server errors).

Source

Thrown at internal/infrastructure/web_search/ollama.go:125

	return req, nil
}

func (p *OllamaProvider) doSearch(ctx context.Context, req *http.Request) ([]*types.WebSearchResult, error) {
	resp, err := p.client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusOK {
		logger.Warnf(ctx, "[WebSearch][Ollama] API returned status %d: %s", resp.StatusCode, string(body))
		return nil, fmt.Errorf("ollama API returned status %d: %s", resp.StatusCode, string(body))
	}

	var respData ollamaSearchResponse
	if err := json.Unmarshal(body, &respData); err != nil {
		return nil, fmt.Errorf("failed to unmarshal response: %w", err)
	}

	results := make([]*types.WebSearchResult, 0, len(respData.Results))
	for _, item := range respData.Results {
		results = append(results, &types.WebSearchResult{
			Title:   item.Title,
			URL:     item.URL,
			Snippet: item.Snippet,
			Content: item.Content,
			Source:  "ollama",
		})
	}
	return results, nil

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Read the status code and body in the error message to identify the upstream cause
  2. Verify the Ollama base URL points at the correct search API endpoint
  3. Check Ollama server logs for the corresponding request failure
  4. Retry with backoff for transient 5xx/429 statuses; fix config for 4xx

Example fix

// before
baseURL := "http://localhost:11434/v1/search" // wrong path
// after
baseURL := os.Getenv("OLLAMA_BASE_URL") // e.g. http://localhost:11434, provider appends correct path
Defensive patterns

Strategy: try-catch

Validate before calling

if !strings.HasPrefix(ollamaBaseURL, "http") {
    return fmt.Errorf("ollama base URL must start with http(s)://")
}

Type guard

func isStatusError(err error) (int, bool) {
    var se int
    if n, _ := fmt.Sscanf(err.Error(), "ollama API returned status %d", &se); n == 1 && se != http.StatusOK {
        return se, true
    }
    return 0, false
}

Try / catch

res, err := searchClient.Search(ctx, query)
if err != nil {
    if code, ok := isStatusError(err); ok && code >= 500 || code == http.StatusTooManyRequests {
        // transient: retry with backoff
    } else if ok {
        // permanent: fail fast, surface body from err message
        return fmt.Errorf("ollama search unavailable (status %d)", code)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Search -> doSearch when the Ollama server returns e.g. 404 (wrong path), 401/403 (auth), 429 (rate limit), or 500; any non-OK status triggers it with the body included in the message.

Common situations: Misconfigured Ollama base URL (hitting a wrong endpoint), Ollama version without the web-search API, reverse proxy or gateway returning HTML error pages, Ollama overloaded or shutting down.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/c8e964732e18aa8b. Report an issue: GitHub.