xpzouying/xiaohongshu-mcp · error

HTTP %d: %s

Error message

HTTP %d: %s

What it means

downloadFile performs the actual browser archive download with a 10-minute HTTP client and writes the body to dst. This error is thrown when the server responds with a status other than 200 OK, aborting the download before any file is created.

Source

Thrown at browser/browser_download.go:197

		}
		return nil
	})
	if found != "" {
		if err := os.Chmod(found, 0o755); err != nil {
			logrus.Debugf("chmod %s: %v", found, err)
		}
	}
	return found
}

func downloadFile(url, dst string) error {
	resp, err := (&http.Client{Timeout: 10 * time.Minute}).Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("HTTP %d: %s", resp.StatusCode, url)
	}
	f, err := os.Create(dst)
	if err != nil {
		return err
	}
	defer f.Close()
	_, err = io.Copy(f, resp.Body)
	return err
}

func extractArchive(archivePath, destDir string) error {
	switch {
	case strings.HasSuffix(archivePath, ".tar.xz"):
		return extractTarXz(archivePath, destDir)
	case strings.HasSuffix(archivePath, ".zip"):
		return extractZip(archivePath, destDir)
	case strings.HasSuffix(archivePath, ".dmg"):
		return extractDmg(archivePath, destDir)

View on GitHub (pinned to 332d196854)

Solutions

  1. Fetch the URL with curl -I to see the exact status and any redirect target
  2. Confirm the URL matches a currently published release for your OS/arch (404 usually means removed or wrong path)
  3. For 403/429, check proxy/firewall rules and retry with backoff or from a different network
  4. For 5xx, retry EnsureBrowser later — CDN outages are usually transient
  5. Update the pinned browser version to one that still has downloadable assets

Example fix

// before
resp, err := (&http.Client{Timeout: 10 * time.Minute}).Get(url)
if err != nil { return err }
// after — follow redirects explicitly and retry on transient statuses
client := &http.Client{Timeout: 10 * time.Minute, CheckRedirect: nil}
for attempt := 0; attempt < 3; attempt++ {
	resp, err := client.Get(url)
	if err == nil && resp.StatusCode == http.StatusOK { break }
	time.Sleep(2 * time.Second)
}
Defensive patterns

Strategy: retry

Validate before calling

resp, err := http.Head(url)
if err != nil || resp.StatusCode != http.StatusOK {
	// 下载地址不可用,先解决再调用 EnsureBrowser
}

Try / catch

if err := EnsureBrowser(ctx); err != nil {
	if strings.Contains(err.Error(), "HTTP ") {
		// 指数退避重试
		time.Sleep(10 * time.Second)
		err = EnsureBrowser(ctx)
	}
	if err != nil { log.Fatal(err) }
}

Prevention

When it happens

Trigger: EnsureBrowser -> downloadFile(url, dst) issues http.Get(url); the request succeeds but the CDN returns e.g. 404 (asset removed/renamed), 403 (blocked/rate limited), or 5xx (server error).

Common situations: Pinned browser version was deleted upstream; download URL constructed for the wrong OS/arch; corporate proxy or geo-block returns 403; CDN outage returns 502/503; GitHub-style rate limiting during CI with shared IPs.

Related errors


AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05). Data as JSON: /api/errors/bc2cbb94c957fb31. Report an issue: GitHub.