chenhg5/cc-connect · error
%s: CDN response missing x-encrypted-param
Error message
%s: CDN response missing x-encrypted-param
What it means
After a 200 OK upload response, uploadBufferToCDN requires the x-encrypted-param response header, which carries the download parameter needed for receivers to fetch the file. A 200 without this header means the CDN accepted the bytes but did not return the download handle, so the upload result is unusable. This is treated as a retryable failure (logged via slog.Warn, loop continues).
Source
Thrown at platform/weixin/cdn.go:216
if resp.StatusCode >= 400 && resp.StatusCode < 500 {
msg := resp.Header.Get("x-error-message")
if msg == "" {
msg = resp.Status
}
return "", fmt.Errorf("%s: CDN upload client error %d: %s", label, resp.StatusCode, msg)
}
if resp.StatusCode != http.StatusOK {
msg := resp.Header.Get("x-error-message")
if msg == "" {
msg = fmt.Sprintf("status %d", resp.StatusCode)
}
lastErr = fmt.Errorf("%s: CDN upload server error: %s", label, msg)
slog.Warn("weixin: CDN upload server error", "label", label, "attempt", attempt, "error", lastErr)
continue
}
dl := resp.Header.Get("x-encrypted-param")
if dl == "" {
lastErr = fmt.Errorf("%s: CDN response missing x-encrypted-param", label)
slog.Warn("weixin: CDN upload bad response", "label", label, "attempt", attempt)
continue
}
return dl, nil
}
if lastErr != nil {
return "", fmt.Errorf("%s: CDN upload failed after %d attempts: %w", label, cdnUploadMaxRetries, lastErr)
}
return "", fmt.Errorf("%s: CDN upload failed after %d attempts", label, cdnUploadMaxRetries)
}
func md5Hex(b []byte) string {
h := md5.Sum(b)
return hex.EncodeToString(h[:])
}
func detectImageMime(b []byte) string {
if len(b) >= 3 && b[0] == 0xFF && b[1] == 0xD8 && b[2] == 0xFF {View on GitHub (pinned to 4000b2338a)
Solutions
- Verify cdn_base points at the official CDN (https://novac2c.cdn.weixin.qq.com/c2c), not a proxy that strips x-encrypted-param
- Check for an updated WeChat iLink CDN contract (header renamed) and update the client
- Retry — the function retries up to 3 attempts; transient edge misbehavior can omit the header
- Log the full response headers on failure to confirm what the CDN actually returned
Defensive patterns
Strategy: validation
Validate before calling
// after upload success, verify the download param before returning
if downloadParam == "" { return fmt.Errorf("upload ok but no download param") } Try / catch
if err != nil && strings.Contains(err.Error(), "missing x-encrypted-param") {
// retry once; if it repeats, the CDN contract/proxy changed — alert an operator
} Prevention
- Do not route CDN traffic through proxies that strip custom x-* response headers
- Pin and periodically re-verify cdn_base against the official value
- Log full response headers on upload to detect contract changes quickly
- Subscribe to WeChat iLink API change announcements
When it happens
Trigger: CDN responds HTTP 200 but omits the x-encrypted-param header; typically an unexpected/changed CDN response contract or a proxy stripping response headers.
Common situations: WeChat iLink API version changes altering the CDN response shape; corporate proxy or middleware stripping custom x-* headers; hitting a wrong/misconfigured cdn_base endpoint that accepts uploads but speaks a different protocol.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- %s: CDN upload client error %d: %s
- %s: CDN upload failed after %d attempts: %w
- %s: CDN upload failed after %d attempts
- %s: upload audio: no file_key returned
- %s: upload video: no file_key returned
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/100d5e6846179167.
Report an issue: GitHub.