router-for-me/CLIProxyAPI · error
decode Claude OAuth response: unsupported content encoding %
Error message
decode Claude OAuth response: unsupported content encoding %q
What it means
The response decoder switches over a fixed set of supported Content-Encoding values (gzip, deflate, br, compress) and rejects anything else. This error names the exact unsupported token, so the value in the message tells you what the server or an intermediary sent. It is a protocol-contract mismatch, not a transient failure.
Source
Thrown at internal/auth/claude/oauth_response.go:61
case "gzip":
gzipReader, errGzip := gzip.NewReader(bytes.NewReader(encoded))
if errGzip != nil {
return nil, fmt.Errorf("decode Claude OAuth gzip response: %w", errGzip)
}
reader = gzipReader
case "deflate":
zlibReader, errZlib := zlib.NewReader(bytes.NewReader(encoded))
if errZlib == nil {
reader = zlibReader
} else {
reader = flate.NewReader(bytes.NewReader(encoded))
}
case "br":
reader = io.NopCloser(brotli.NewReader(bytes.NewReader(encoded)))
case "compress":
reader = lzw.NewReader(bytes.NewReader(encoded), lzw.MSB, 8)
default:
return nil, fmt.Errorf("decode Claude OAuth response: unsupported content encoding %q", encoding)
}
decoded, errDecoded := io.ReadAll(reader)
if errDecoded != nil {
_ = reader.Close()
return nil, fmt.Errorf("decode Claude OAuth %s response: %w", encoding, errDecoded)
}
if errClose := reader.Close(); errClose != nil {
return nil, fmt.Errorf("close Claude OAuth %s decoder: %w", encoding, errClose)
}
return decoded, nil
}
View on GitHub (pinned to 78f0c4079e)
Solutions
- Set Accept-Encoding on the OAuth request to only the encodings the decoder supports (e.g. "gzip, deflate, br") so the server never picks zstd.
- Remove custom Accept-Encoding overrides and let the client negotiate.
- Extend the switch in decodeClaudeOAuthEncoding with a case for the reported encoding if your fork needs it (zstd via klauspost/compress).
- Report/inspect the exact %q value in the message to identify which hop introduced it.
Example fix
// before
req.Header.Set("Accept-Encoding", "zstd, gzip, br")
// after
req.Header.Set("Accept-Encoding", "gzip, deflate, br") Defensive patterns
Strategy: validation
Validate before calling
supported := map[string]bool{"gzip": true, "deflate": true, "br": true, "compress": true}
if enc := strings.ToLower(strings.TrimSpace(resp.Header.Get("Content-Encoding"))); enc != "" && !supported[enc] {
return fmt.Errorf("server picked unsupported encoding %q; resend with restricted Accept-Encoding", enc)
} Prevention
- Pin Accept-Encoding to the decoders you support; never forward arbitrary encodings.
- Log the %q token from the message to find which hop injects exotic encodings.
When it happens
Trigger: The OAuth response arrives with Content-Encoding: zstd (or any value outside the switch), a combined encoding such as "gzip, br", a case variant, or an empty/garbage header injected by a custom proxy. Only the exact lowercase single tokens gzip/deflate/br/compress are accepted.
Common situations: Upstream adds zstd support and starts advertising it; a developer sets a custom Accept-Encoding header (e.g. "zstd") on the OAuth request; proxies that append or rewrite encoding headers; case-mismatched headers from non-standard gateways.
Related errors
- decode Claude OAuth gzip response: %w
- decode Claude OAuth %s response: %w
- close Claude OAuth %s decoder: %w
- fetch Claude OAuth %s: HTTP client is nil
- fetch Claude OAuth %s: access token is empty
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/23e082672fde387b.
Report an issue: GitHub.