siyuan-note/siyuan · error
download failed:
Error message
download failed:
What it means
fetchBytes performs the actual GET with the shared httpclient; if the HTTP transport itself fails (connection error, DNS failure, TLS error, timeout), the underlying error text is wrapped in a fixed `download failed: ` prefix (note: no HTTP status here — status failures produce `download failed: HTTP <code>` instead).
Source
Thrown at kernel/util/skill.go:699
// codeload main 分支 404 时回退 master
if src.isZip && src.branch == "main" {
ownerRepo := strings.TrimPrefix(strings.TrimPrefix(src.downloadURL, "https://codeload.github.com/"), "http://codeload.github.com/")
ownerRepo = strings.TrimSuffix(ownerRepo, "/zip/refs/heads/main")
fallback := codeloadSource(ownerRepo, "master")
data, contentType, ferr := fetchBytes(fallback.downloadURL)
if ferr != nil {
return nil, "", fmt.Errorf("download failed (tried main and master): %v", err)
}
return data, contentType, nil
}
return nil, "", err
}
// fetchBytes 执行带大小限制的 GET
func fetchBytes(rawURL string) (data []byte, contentType string, err error) {
resp, err := httpclient.NewBrowserRequest().Get(rawURL)
if err != nil {
return nil, "", errors.New("download failed: " + err.Error())
}
defer resp.Body.Close()
if resp.StatusCode >= 400 {
return nil, "", fmt.Errorf("download failed: HTTP %d", resp.StatusCode)
}
contentType = resp.Header.Get("Content-Type")
body, err := io.ReadAll(io.LimitReader(resp.Body, maxSkillDownloadBytes+1))
if err != nil {
return nil, "", errors.New("read body failed: " + err.Error())
}
if len(body) > maxSkillDownloadBytes {
return nil, "", errors.New("skill source too large (limit 10MB)")
}
return body, contentType, nil
}
View on GitHub (pinned to 8641553a1f)
Solutions
- Check network connectivity to the host in the URL (curl the download URL from the same machine)
- Fix proxy/TLS configuration for the environment (proxy env vars, trusted CA certs)
- Retry after transient failures; the error text (after the prefix) names the root cause
- Use an alternative source URL (mirror, self-hosted zip) reachable from the network
Example fix
// before
util.InstallSkill("https://internal.example.com/skill.zip") // connection refused on restricted network
// after
util.InstallSkill("https://codeload.github.com/owner/repo/zip/refs/heads/main") // reachable host Defensive patterns
Strategy: retry
Validate before calling
// probe reachability before install
resp, err := http.Get("https://codeload.github.com")
if err != nil {
return fmt.Errorf("network unreachable: %w", err)
}
resp.Body.Close() Try / catch
if _, err := util.InstallSkill(src); err != nil {
if strings.HasPrefix(err.Error(), "download failed: ") && !strings.Contains(err.Error(), "HTTP ") {
// transport-level failure: retry with backoff, then report connectivity problem
}
return err
} Prevention
- Check network/proxy reachability to github.com domains before bulk installs
- Configure proxy env vars and trusted CAs for corporate/firewalled environments
- Implement bounded retries with backoff for transient transport errors
- Read the text after the `download failed: ` prefix — it names the underlying DNS/TLS/connection cause
When it happens
Trigger: Any InstallSkill download whose underlying http.Get errors: DNS resolution failure, connection refused/reset, TLS handshake failure, proxy misconfiguration, or request timeout — on codeload.github.com, raw.githubusercontent.com, or any custom direct URL.
Common situations: Offline or firewalled environments blocking github domains; corporate proxies without configured trust; DNS hijacking; IPv6 issues; transient network flaps during skill installation.
Related errors
- read body failed:
- download failed (tried main and master): %v
- read body failed: %s
- download custom emoji failed: %w
- get bazaar package failed, please check your network
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/ee97c8dc6c902620.
Report an issue: GitHub.