micro/go-micro · error

API request failed: %w

Error message

API request failed: %w

What it means

Wraps the transport-level error from http.DefaultClient.Do when POSTing to the Ollama OpenAI-compatible chat endpoint. It means the HTTP request itself failed before a response was received — DNS failure, connection refused, TLS error, or context cancellation/timeout.

Source

Thrown at ai/ollama/ollama.go:244

func (p *Provider) callOpenAI(ctx context.Context, req map[string]any) (*ai.Response, *rawChatMessage, error) {
	reqBody, err := json.Marshal(req)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to marshal request: %w", err)
	}

	apiURL := strings.TrimRight(p.opts.BaseURL, "/") + p.chatPath()
	httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(reqBody))
	if err != nil {
		return nil, nil, fmt.Errorf("failed to create request: %w", err)
	}
	httpReq.Header.Set("Content-Type", "application/json")
	if p.opts.APIKey != "" {
		httpReq.Header.Set("Authorization", "Bearer "+p.opts.APIKey)
	}

	httpResp, err := http.DefaultClient.Do(httpReq)
	if err != nil {
		return nil, nil, fmt.Errorf("API request failed: %w", err)
	}
	defer httpResp.Body.Close()

	respBody, _ := io.ReadAll(httpResp.Body)
	if httpResp.StatusCode != http.StatusOK {
		return nil, nil, fmt.Errorf("API error (%s): %s", httpResp.Status, string(respBody))
	}

	var chatResp struct {
		Usage struct {
			PromptTokens     int `json:"prompt_tokens"`
			CompletionTokens int `json:"completion_tokens"`
			TotalTokens      int `json:"total_tokens"`
		} `json:"usage"`
		Choices []struct {
			Message struct {
				Role      string `json:"role"`
				Content   string `json:"content"`

View on GitHub (pinned to 24529f1404)

Solutions

  1. Confirm the Ollama server is running: curl the BaseURL (e.g. http://localhost:11434) before the call
  2. Check BaseURL host/port/scheme match the actual Ollama endpoint
  3. Increase the context timeout — local LLM generation can be slow
  4. Inspect the wrapped error (errors.Unwrap) to distinguish connection-refused, DNS, TLS, and timeout causes

Example fix

// before
ctx := context.Background()
resp, err := provider.Generate(ctx, req)
// after
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
resp, err := provider.Generate(ctx, req)
if err != nil {
    if urlErr, ok := errors.As(err, &url.Error{}); ok && errors.Is(urlErr.Err, syscall.ECONNREFUSED) {
        // Ollama not reachable — check daemon
    }
}
Defensive patterns

Strategy: retry

Validate before calling

// reachability check before calling
conn, err := net.DialTimeout("tcp", "localhost:11434", 2*time.Second)
if err != nil {
    return fmt.Errorf("ollama server not reachable: %w", err)
}
conn.Close()

Type guard

func isConnectionRefused(err error) bool {
    var urlErr *url.Error
    return errors.As(err, &urlErr) && errors.Is(urlErr.Err, syscall.ECONNREFUSED)
}

Try / catch

resp, err := provider.Generate(ctx, req)
if err != nil {
    var urlErr *url.Error
    if errors.As(err, &urlErr) {
        if errors.Is(urlErr.Err, context.DeadlineExceeded) {
            // increase timeout / retry
        } else if errors.Is(urlErr.Err, syscall.ECONNREFUSED) {
            // start ollama serve
        }
    }
    return err
}

Prevention

When it happens

Trigger: http.DefaultClient.Do(httpReq) returns err in callOpenAI (called from generateOpenAI): Ollama server not running, wrong host/port in BaseURL, network unreachable, TLS handshake failure, or ctx cancelled/expired.

Common situations: Ollama daemon not started (connection refused on localhost:11434); pointing at a remote Ollama host that is down or firewalled; wrong scheme (https vs http) causing TLS errors; request context deadline exceeded on slow generations.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/f1f3d7d2916601db. Report an issue: GitHub.