siyuan-note/siyuan · error
nil response
Error message
nil response
What it means
HTTPRequest in kernel/util/httprequest.go performs an SSRF-safe outbound HTTP call for the agent's http_request tool. After ssrfSafeClient.Do returns without an error, the code defensively checks that a non-nil *http.Response was returned. Go's net/http normally guarantees a non-nil response whenever err is nil, so this error is thrown when an internal invariant of the custom SSRF-safe transport is violated and Do returns (nil, nil).
Source
Thrown at kernel/util/httprequest.go:338
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")
}
respBody, rerr := io.ReadAll(io.LimitReader(resp.Body, maxReadBytes))
if rerr != nil {
return statusCode, contentType, "", errors.New("read body failed: " + rerr.Error())View on GitHub (pinned to 8641553a1f)
Solutions
- Check environment proxy variables (HTTP_PROXY/HTTPS_PROXY/ALL_PROXY, NO_PROXY) and retry with the proxy disabled to confirm the proxy tunnel path is the trigger
- Inspect the ssrfSafeTransport.RoundTrip implementation in kernel/util/httprequest.go for a code path returning nil response with nil error and fix it to always return a non-nil error alongside a nil response
- Update to the latest kernel build in case the transport invariant bug has been patched
- Retry the request once — if it recurs deterministically, report it as a kernel bug with the target URL and proxy configuration
Example fix
// before (in a custom RoundTrip)
if somethingOdd {
return nil, nil // violates net/http contract
}
// after
if somethingOdd {
return nil, errors.New("transport produced no response")
} Defensive patterns
Strategy: try-catch
Validate before calling
// Go has no pre-call validation; the invariant is internal to ssrfSafeClient.
// Sanity-check inputs before the call:
if !strings.HasPrefix(rawURL, "http://") && !strings.HasPrefix(rawURL, "https://") {
return errors.New("URL must start with http:// or https://")
} Type guard
if resp == nil {
// treat as an error path before dereferencing resp
return errors.New("nil response")
} Try / catch
status, ct, text, err := util.HTTPRequest(method, url, headers, body)
if err != nil {
if strings.Contains(err.Error(), "nil response") {
// internal transport invariant violation: log and report, do not retry blindly
return fmt.Errorf("http_request tool returned nil response: %w", err)
}
return err
} Prevention
- Keep the SSRF-safe transport on an unmodified, up-to-date kernel build
- When using proxies, verify the tunnel path behaves correctly with a simple GET before relying on it in automation
- Never dereference the response without checking err and resp for nil
When it happens
Trigger: Calling HTTPRequest(method, rawURL, headers, body) where the ssrfSafeClient's RoundTrip implementation returns (nil, nil) — a bug or edge case in the custom ssrfSafeTransport/proxy tunnel path rather than anything the caller can control via arguments.
Common situations: Encountered when diagnosing the proxy-tunnel transport (HTTP CONNECT or SOCKS5 path) in environments using HTTP_PROXY/HTTPS_PROXY/ALL_PROXY, or after custom modifications to ssrfSafeClient; practically never seen in normal direct-connection usage.
Related errors
- read body failed:
- download failed (tried main and master): %v
- download failed:
- read body failed: %s
- version request returned HTTP " + response.status
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/cdad3583c1d674b6.
Report an issue: GitHub.