siyuan-note/siyuan · error

request failed:

Error message

request failed: 

What it means

ssrfSafeClient.Do executes the request; any transport-level failure (DNS, TCP connect, TLS, timeout, proxy failure, context cancel) is wrapped as 'request failed: <cause>'. The inner error text names the actual cause, so it should be read, not discarded.

Source

Thrown at kernel/util/httprequest.go:335

	if method == "" {
		method = "GET"
	}

	var reqBody io.Reader
	if body != "" && method != "GET" && method != "HEAD" {
		reqBody = strings.NewReader(body)
	}
	req, err := http.NewRequest(method, rawURL, reqBody)
	if err != nil {
		return 0, "", "", errors.New("invalid request: " + err.Error())
	}
	for k, v := range headers {
		req.Header.Set(k, v)
	}

	resp, err := ssrfSafeClient.Do(req)
	if err != nil {
		return 0, "", "", errors.New("request failed: " + err.Error())
	}
	if resp == nil {
		return 0, "", "", errors.New("nil response")
	}
	defer resp.Body.Close()

	statusCode = resp.StatusCode
	contentType = resp.Header.Get("Content-Type")

	maxReadBytes := int64(maxHTTPRequestBytes)
	if !isTextContentType(contentType) {
		maxReadBytes = maxHTTPRequestFileBytes
	}
	// ContentLength 为 -1(chunked)时跳过大小预检,交由 LimitReader 兜底截断。
	if resp.ContentLength > maxReadBytes {
		return statusCode, contentType, "", errors.New("response too large")
	}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Read the wrapped cause: 'connection refused' → service/port wrong; 'no such host' → DNS; 'certificate is valid for' → TLS/SNI problem; 'context deadline exceeded' → raise timeout
  2. Verify the service is up and reachable with `curl -v <url>` from the same machine
  3. Fix TLS issues (valid cert) rather than disabling verification
  4. Add retry with backoff for transient network errors and a sane timeout on the context

Example fix

// before
HTTPRequest("GET", "https://api.example.com:9999/v1", nil, "") // wrong port, connection refused
// after
HTTPRequest("GET", "https://api.example.com:443/v1", nil, "")
Defensive patterns

Strategy: try-catch

Validate before calling

if u, err := url.Parse(rawURL); err != nil || u.Host == "" || (u.Scheme != "http" && u.Scheme != "https") {
    return errors.New("URL must be an absolute http(s) URL")
}

Try / catch

status, _, _, err := HTTPRequest("GET", url, nil, "")
if err != nil {
    if strings.HasPrefix(err.Error(), "request failed: ") && isTransient(err) {
        time.Sleep(backoff)
        return HTTPRequest("GET", url, nil, "") // retry once
    }
    return err
}

Prevention

When it happens

Trigger: HTTPRequest called against a host that is unreachable, refuses connections, has bad TLS, or where the context deadline expires during Do; also failures inside the SSRF-safe transport's proxy tunnel.

Common situations: Target server down or wrong port; TLS certificate invalid/expired/self-signed; firewall dropping outbound traffic; request timeout too small; proxy misconfiguration surfacing here after passing the earlier checks.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/4a647dc871b0596f. Report an issue: GitHub.