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

  1. 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.
  2. Remove custom Accept-Encoding overrides and let the client negotiate.
  3. Extend the switch in decodeClaudeOAuthEncoding with a case for the reported encoding if your fork needs it (zstd via klauspost/compress).
  4. 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

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


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/23e082672fde387b. Report an issue: GitHub.