# How to Troubleshoot Connection Errors with kimi-cli: Complete Diagnostics Guide

> Troubleshoot kimi-cli connection errors like APIConnectionError and APITimeoutError with this complete diagnostics guide. Learn to resolve API issues and ensure smooth operation.

- Repository: [Moonshot AI/kimi-cli](https://github.com/MoonshotAI/kimi-cli)
- Tags: how-to-guide
- Published: 2026-07-28

---

**Connection errors in kimi-cli surface as `APIConnectionError`, `APITimeoutError`, or `APIEmptyResponseError` from the kosong provider layer, which the `KimiSoul` core loop classifies, retries automatically, and surfaces to the UI with specific remediation steps such as running `/login` for authentication failures.**

The `kimi-cli` tool by MoonshotAI communicates with LLM providers through the **kosong** chat-provider abstraction. When HTTP connectivity fails, the runtime transforms raw socket errors into structured `ChatProviderError` subclasses, enabling automated recovery flows and actionable user feedback to help you troubleshoot connection errors with kimi-cli efficiently.

## Understanding Connection Error Types

The kosong abstraction defines three primary exceptions that indicate network-level failures. In `packages/kosong/src/kosong/chat_provider/__init__.py#L46-L50`, the provider raises:

- **`APIConnectionError`**: Indicates the HTTP client cannot establish a TCP connection due to socket errors, DNS resolution failures, or proxy misconfigurations.
- **`APITimeoutError`**: Raised when a request exceeds the configured timeout duration.
- **`APIEmptyResponseError`**: Signifies a successful TCP connection that returned an empty payload.

These exceptions inherit from `ChatProviderError` and propagate through the `KimiSoul` event loop for classification and handling.

## Error Classification and Telemetry

Before displaying an error, `KimiSoul` maps raw exceptions to shorthand types for telemetry and UI color-coding. The `classify_api_error` function in `src/kimi_cli/soul/kimisoul.py#L14-L53` implements this logic:

```python
def classify_api_error(e: Exception) -> tuple[str, int | None]:
    …
    if isinstance(e, APIConnectionError):
        return "network", None
    if isinstance(e, (APITimeoutError, TimeoutError)):
        return "timeout", None
    …

```

This classification feeds the `_track_api_error` telemetry helper (lines L91‑L99) and determines the color and message shown in the terminal interface.

## Automatic Retry and Recovery Logic

`KimiSoul` wraps every LLM invocation in a tenacity retry loop that consults `_is_retryable_error` to determine whether to attempt recovery. As implemented in `src/kimi_cli/soul/kimisoul.py#L46-L58`:

```python
def _is_retryable_error(exception: BaseException) -> bool:
    if isinstance(exception, (APIConnectionError, APITimeoutError)):
        return not bool(getattr(exception, "_kimi_recovery_exhausted", False))
    …
    return isinstance(exception, APIStatusError) and exception.status_code in (
        429, 500, 502, 503, 504,
    )

```

For transient failures, `_run_with_connection_recovery` (lines L60‑L100) attempts an OAuth token refresh when the provider supports it, then re-executes the original operation:

```python
async def _run_with_connection_recovery(...):
    try:
        return await operation()
    except APIStatusError as error:
        if error.status_code != 401 or _auth_retried:
            raise
        …
        await self._runtime.oauth.ensure_fresh(self._runtime, force=True)
        return await self._run_with_connection_recovery(..., _auth_retried=True)

```

If the provider uses API-key authentication only, the retry logic skips the refresh step and proceeds with exponential backoff.

## Configuration Issues That Trigger Connection Errors

Several environment and configuration variables directly impact connectivity:

- **API Keys** (`KIMI_API_KEY`, `OPENAI_API_KEY`, …): Loaded in [`src/kimi_cli/llm.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/llm.py#L289)‑L311). Missing or incorrect keys result in 401 errors that the UI reports as "Authorization failed".
- **Proxy Environment** (`ALL_PROXY`, `HTTP_PROXY`, …): Normalized in `src/kimi_cli/utils/proxy.py#L20-L32`. The helper automatically rewrites `socks://` to `socks5://` because `httpx` does not support the former, preventing `APIConnectionError`.
- **OAuth Token Expiry**: Handled in `src/kimi_cli/soul/kimisoul.py#L72‑L90`. When an OAuth provider returns 401, the system attempts automatic token refresh before surfacing the error.
- **HTTP Header Whitespace**: A known Linux kernel bug can introduce trailing newlines in headers; the codebase strips these before sending to prevent server rejection.

## Step-by-Step Diagnostic Workflow

Follow this sequence to isolate and resolve connectivity issues:

1. **Check the UI message**: The terminal already indicates whether the failure is a network, timeout, authentication, or server-side error.
2. **Inspect the log**: Search for the `logger.exception("LLM provider error:")` line in the shell or print UI output; the stack trace reveals the original exception class.
3. **Validate environment**: Run `echo $KIMI_API_KEY` (or the provider-specific key) and `env | grep -i proxy` to verify variables are set.
4. **Force a token refresh**: Execute `/login` in the interactive shell to re-authenticate any OAuth session.
5. **Run a minimal request**: Test with `kimi ask "Hello"`; if it fails, use `curl` against the provider endpoint to rule out system-wide networking issues.
6. **Enable debug mode**: Set `KIMI_LOG_LEVEL=DEBUG` (via environment or `.env`) to capture verbose output from `loguru`.

## Code Examples for Debugging Connection Issues

### Reproduce a Connection Error with a Mock Provider

Use this pattern to test how the UI handles network failures:

```python
from kosong.chat_provider import APIConnectionError
from kimi_cli.soul.kimisoul import KimiSoul

class BrokenProvider:
    async def chat(self, *_, **__):
        raise APIConnectionError("simulated network failure")

# Inject the broken provider into a fresh runtime (simplified)

runtime = ...   # obtain a Runtime instance via KimiCLI.create()

runtime.llm = BrokenProvider()
soul = KimiSoul(runtime)

# This triggers the retry loop and surfaces the error to the UI

await soul.run_once()

```

### Verify Environment Variables

Run this script to audit your configuration:

```python
import os
for var in ("KIMI_API_KEY", "OPENAI_API_KEY", "ALL_PROXY", "HTTP_PROXY"):
    print(f"{var} = {os.getenv(var)!r}")

```

### Trigger Manual Token Refresh

In the interactive shell, execute:

```bash
/login

```

The CLI initiates the provider-specific login flow, refreshing OAuth tokens or updating API keys as needed.

## Summary

- **`kimi-cli` converts low-level HTTP failures** into structured `ChatProviderError` subclasses (`APIConnectionError`, `APITimeoutError`, `APIEmptyResponseError`) defined in the kosong abstraction layer.
- **Automatic retry logic** in `KimiSoul` handles transient errors and attempts OAuth token refresh for 401 responses before giving up.
- **Proxy auto-correction** prevents common `socks://` misconfigurations that crash `httpx` connections.
- **Diagnostic clarity** comes from checking UI color codes, inspecting logs for the full stack trace, and validating `KIMI_API_KEY` and proxy environment variables.
- **Re-authentication** via `/login` resolves most authorization-related connection failures.

## Frequently Asked Questions

### What does `APIConnectionError` mean in kimi-cli?

`APIConnectionError` indicates the HTTP client could not establish a TCP connection to the LLM provider, typically caused by DNS resolution failures, socket timeouts, or proxy misconfigurations in [`src/kimi_cli/utils/proxy.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/utils/proxy.py). Check your network connectivity and proxy settings, then verify the endpoint is reachable with a tool like `curl`.

### How do I fix proxy-related connection errors?

Ensure your `ALL_PROXY` or `HTTP_PROXY` variables use `socks5://` instead of `socks://`, as the underlying `httpx` library does not support the latter scheme. The proxy normalization logic in `src/kimi_cli/utils/proxy.py#L20-L32` attempts to auto-correct this, but explicit `socks5://` formatting prevents initialization errors.

### Why does kimi-cli retry failed requests multiple times?

The `KimiSoul` core loop implements a tenacity-based retry mechanism that treats `APIConnectionError`, `APITimeoutError`, and specific HTTP status codes (429, 500, 502, 503, 504) as transient. It attempts recovery—including OAuth token refresh for 401 errors—before surfacing a final error to the user interface.

### How do I re-authenticate when I see an authorization failure?

When the UI displays "Authorization failed" (usually accompanied by a 401 status code), type `/login` in the interactive shell. This forces a fresh OAuth token refresh or API key re-entry, which the `_run_with_connection_recovery` method in [`src/kimi_cli/soul/kimisoul.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/soul/kimisoul.py) executes automatically during the next request attempt.