chenhg5/cc-connect · error
read cdn response: %w
Error message
read cdn response: %w
What it means
After a 200 from the CDN upload POST, uploadAttachment reads up to 64 KiB of the response body to extract the attachment token. If that read fails (connection reset mid-response, context deadline exceeded while reading, chunked-body corruption), the error is wrapped as "read cdn response: %w". The upload itself succeeded server-side, but the token needed for the follow-up /messages attachment could not be retrieved.
Source
Thrown at platform/max/max.go:605
cdnReq, err := http.NewRequestWithContext(uploadCtx, http.MethodPost, urlInfo.URL, &buf)
if err != nil {
return "", err
}
p.setAuth(cdnReq)
cdnReq.Header.Set("Content-Type", mw.FormDataContentType())
cdnResp, err := p.uploadClient.Do(cdnReq)
if err != nil {
return "", fmt.Errorf("cdn upload: %w", err)
}
defer cdnResp.Body.Close()
if cdnResp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(io.LimitReader(cdnResp.Body, 512))
return "", fmt.Errorf("cdn upload: HTTP %d: %s", cdnResp.StatusCode, body)
}
cdnBody, err := io.ReadAll(io.LimitReader(cdnResp.Body, 64*1024))
if err != nil {
return "", fmt.Errorf("read cdn response: %w", err)
}
// MAX CDN uses different response shapes per attachment kind:
// image: {"photos": {"<photo_id>": {"token": "..."}}}
// file: {"token": "..."}
// video/audio: "<retval>1</retval>" (XML) — the real token is already in urlInfo.Token
if token := extractCDNToken(kind, cdnBody); token != "" {
return token, nil
}
if urlInfo.Token != "" {
return urlInfo.Token, nil
}
return "", fmt.Errorf("cdn upload: no token in response: %s", cdnBody)
}
// extractCDNToken parses the token out of a MAX CDN upload response. Returns
// "" if not found; the caller is expected to fall back to urlInfo.Token.
func extractCDNToken(kind string, body []byte) string {
switch kind {View on GitHub (pinned to 4000b2338a)
Solutions
- Retry the whole upload — since the CDN likely stored the file, a fresh upload replaces it cleanly.
- Check network stability to the CDN host (packet loss, MTU issues with VPNs).
- Verify the 5-minute context isn't being preemptively canceled by the caller.
- If it recurs with one CDN host, log the host and report it; consider pinning IPv4 in the Transport if IPv6 is flaky.
Example fix
// before
var token string
var err error
token, err = p.uploadAttachment(ctx, kind, data, filename)
// after: bounded retry for transient read failures
var token string
var err error
for i := 0; i < 2; i++ {
token, err = p.uploadAttachment(ctx, kind, data, filename)
if err == nil || !strings.Contains(err.Error(), "read cdn response") {
break
}
time.Sleep(time.Second)
} Defensive patterns
Strategy: retry
Validate before calling
// Ensure the upload context has enough headroom before starting
if deadline, ok := ctx.Deadline(); ok && time.Until(deadline) < attachmentUploadTO {
return fmt.Errorf("insufficient context budget for upload: %v left", time.Until(deadline))
} Type guard
func isReadFailure(err error) bool {
return strings.Contains(err.Error(), "read cdn response:")
} Try / catch
token, err := p.uploadAttachment(ctx, kind, data, filename)
if err != nil {
if strings.Contains(err.Error(), "read cdn response:") {
// retry once: transient stream interruption, full re-upload is idempotent
time.Sleep(time.Second)
token, err = p.uploadAttachment(ctx, kind, data, filename)
}
} Prevention
- Retry whole uploads on read failures — the CDN state from the failed attempt is harmless.
- Monitor network stability (packet loss, MTU) between the bot host and the CDN.
- Avoid canceling the session context while an attachment send is in flight.
- Keep the 64 KiB response cap in mind; never assume an unbounded response body.
When it happens
Trigger: SendImage/SendFile/SendAudio where the CDN's 200 response body cannot be fully read within the 5-minute upload context — typically connection reset by the CDN, context cancellation, or a stalled/slow response stream.
Common situations: Unstable networks interrupting the response; CDN servers under load returning truncated chunked responses; the 5-minute attachmentUploadTO deadline firing during the read of a very large response (rare, since the body is capped at 64 KiB).
Related errors
- read upload response: %w
- request upload url: %w
- cdn upload: %w
- read body from %s: %w
- read body from %s: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/5fd00d0c2bfe9aaa.
Report an issue: GitHub.