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

  1. Verify cdn_base points at the official CDN (https://novac2c.cdn.weixin.qq.com/c2c), not a proxy that strips x-encrypted-param
  2. Check for an updated WeChat iLink CDN contract (header renamed) and update the client
  3. Retry — the function retries up to 3 attempts; transient edge misbehavior can omit the header
  4. 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

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


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/100d5e6846179167. Report an issue: GitHub.