router-for-me/CLIProxyAPI · error
kimi: failed to read refresh response: %w
Error message
kimi: failed to read refresh response: %w
What it means
Reading the refresh response body failed mid-stream after response headers arrived (io.ReadAll error on POST /api/oauth/token with grant_type=refresh_token). Transport-level interruption, not an OAuth decision — the status line was received but the payload was cut off.
Source
Thrown at internal/auth/kimi/kimi.go:397
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Accept", "application/json")
for k, v := range c.commonHeaders() {
req.Header.Set(k, v)
}
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("kimi: refresh request failed: %w", err)
}
defer func() {
if errClose := resp.Body.Close(); errClose != nil {
log.Errorf("kimi refresh token: close body error: %v", errClose)
}
}()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("kimi: failed to read refresh response: %w", err)
}
if resp.StatusCode == http.StatusUnauthorized || resp.StatusCode == http.StatusForbidden {
return nil, fmt.Errorf("kimi: refresh token rejected (status %d)", resp.StatusCode)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("kimi: refresh failed with status %d: %s", resp.StatusCode, string(bodyBytes))
}
var tokenResp struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
TokenType string `json:"token_type"`
ExpiresIn float64 `json:"expires_in"`
Scope string `json:"scope"`
}
View on GitHub (pinned to 78f0c4079e)
Solutions
- Retry the refresh — connection-reuse races clear on a new connection; singleflight dedup means just invoking RefreshToken again suffices
- If frequent, reduce httpClient idle-connection reuse issues by adjusting transport settings or restarting the process
- Check for intermediary proxies truncating long-lived connections to auth.kimi.com
Defensive patterns
Strategy: retry
Try / catch
if err != nil && strings.Contains(err.Error(), "failed to read refresh response") {
// connection reuse race: immediate retry on fresh connection usually succeeds
return c.RefreshToken(ctx, refreshToken)
} Prevention
- Retry refresh once on mid-body read failures
- Tune transport idle-connection settings if races recur
- Avoid proxies that cut long response streams
When it happens
Trigger: Connection reset or proxy stream cut during refresh response; truncated chunked transfer; idle-connection reuse race where the pooled connection is closed just as the body streams.
Common situations: Keep-alive connection reuse races under load (server closes pooled connection mid-read), proxies with aggressive stream timeouts, flaky egress.
Related errors
- kimi: refresh request failed: %w
- kimi: failed to read device code response: %w
- kimi: token request failed: %w
- kimi: failed to read token response: %w
- kimi: failed to create refresh request: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/945c234ee21db145.
Report an issue: GitHub.