router-for-me/CLIProxyAPI · error
kimi: failed to read device code response: %w
Error message
kimi: failed to read device code response: %w
What it means
The HTTP POST to Kimi's device authorization endpoint (https://auth.kimi.com/api/oauth/device_authorization) succeeded at the transport level, but reading the response body with io.ReadAll failed. This means the connection was interrupted between receiving response headers and receiving the full body. The device code was never obtained, so the device flow cannot proceed.
Source
Thrown at internal/auth/kimi/kimi.go:207
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: device code request failed: %w", err)
}
defer func() {
if errClose := resp.Body.Close(); errClose != nil {
log.Errorf("kimi device code: close body error: %v", errClose)
}
}()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("kimi: failed to read device code response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("kimi: device code request failed with status %d: %s", resp.StatusCode, string(bodyBytes))
}
var deviceCode DeviceCodeResponse
if err = json.Unmarshal(bodyBytes, &deviceCode); err != nil {
return nil, fmt.Errorf("kimi: failed to parse device code response: %w", err)
}
return &deviceCode, nil
}
// PollForToken polls the token endpoint until the user authorizes or the device code expires.
func (c *DeviceFlowClient) PollForToken(ctx context.Context, deviceCode *DeviceCodeResponse) (*KimiTokenData, error) {
if deviceCode == nil {
return nil, fmt.Errorf("kimi: device code is nil")View on GitHub (pinned to 78f0c4079e)
Solutions
- Retry StartDeviceFlow once — this is a transient transport failure and a new request gets a fresh connection
- Check whether an HTTP(S) proxy (HTTP_PROXY/HTTPS_PROXY env vars) is interfering and bypass or configure it for auth.kimi.com
- Verify basic connectivity: curl -i -X POST https://auth.kimi.com/api/oauth/device_authorization and confirm the body arrives fully
- If it persists, inspect httpClient timeout configuration in NewDeviceFlowClient — a very short client timeout can abort mid-body reads
Example fix
// before
deviceCode, err := k.StartDeviceFlow(ctx)
if err != nil {
return err // fails outright on transient body read error
}
// after
deviceCode, err := k.StartDeviceFlow(ctx)
if err != nil {
if isTransientNetErr(err) { // net.Error, io.ErrUnexpectedEOF, connection reset
time.Sleep(2 * time.Second)
deviceCode, err = k.StartDeviceFlow(ctx)
}
if err != nil {
return err
}
} Defensive patterns
Strategy: retry
Validate before calling
// Verify the auth host is reachable and proxy env is sane before starting the flow
if _, err := net.LookupHost("auth.kimi.com"); err != nil {
return fmt.Errorf("cannot resolve auth.kimi.com: %w", err)
} Try / catch
if err != nil && strings.Contains(err.Error(), "failed to read device code response") {
time.Sleep(2 * time.Second)
deviceCode, err = k.StartDeviceFlow(ctx)
} Prevention
- Exclude auth.kimi.com from MITM/intercepting proxies
- Ensure stable egress before starting interactive login
- Treat any single transport failure on device code as retryable
When it happens
Trigger: Connection reset or TLS renegotiation mid-body while auth.kimi.com streams the device code JSON; an intercepting proxy that closes the stream early; response with Content-Length larger than what the server actually sends; very slow network causing the client reader to abort.
Common situations: Corporate proxies/MITM proxies truncating responses, flaky mobile or containerized networks, transient Moonshot-side connection resets, running in CI with restricted egress that allows headers but drops body.
Related errors
- kimi: token request failed: %w
- kimi: failed to read token response: %w
- kimi: device code request failed: %w
- kimi: device code request failed with status %d: %s
- kimi: failed to create token request: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/9758a24a4ef82392.
Report an issue: GitHub.