siyuan-note/siyuan · error
generated image redirect is not allowed
Error message
generated image redirect is not allowed
What it means
The image download HTTP client installs a CheckRedirect hook as part of SSRF protection: at most 2 redirects are followed, every redirected URL must remain https, and each hop's host must pass CheckHostSSRF. Violating any of these aborts with this error, so a provider cannot bounce the request to http:// or to an internal address.
Solutions
- Get the provider to return a direct, non-redirecting https image URL
- If a redirect chain is legitimate, increase the hop limit in generatedImageHTTPClient's CheckRedirect (only for trusted hosts)
- Fix the server so redirects preserve https scheme
- Ensure the final host is a public address that passes CheckHostSSRF
Example fix
// before Location: "http://cdn.example.com/img.png" // https->http redirect blocked // after Location: "https://cdn.example.com/img.png" // allowed (scheme stays https)
Defensive patterns
Strategy: validation
Validate before calling
func nextHopOK(u *url.URL) error {
if u.Scheme != "https" || u.Host == "" { return errors.New("bad redirect target") }
return CheckHostSSRF(u.Hostname())
} Try / catch
if errors.Is(err, errRedirectBlocked) || strings.Contains(err.Error(), "redirect is not allowed") {
return fmt.Errorf("image host redirected unsafely; refusing download")
} Prevention
- Always set CheckRedirect on clients fetching provider-controlled URLs
- Re-run SSRF host checks on every redirect hop
- Keep the redirect limit small for untrusted hosts
When it happens
Trigger: The image URL responds with 3xx Location that is (a) the 3rd+ redirect in the chain, (b) an http:// or non-https scheme, or the next hop's hostname fails CheckHostSSRF.
Common situations: CDN redirecting https → http; redirect chains longer than 2 hops (auth gateway → CDN); redirect to an internal/private hostname (classic SSRF); expired URL redirecting to a login page over http.
Related errors
- generated image URL must use HTTPS
- access to private/internal IP is prohibited
- access to private/internal IP is prohibited
- failed to resolve host:
- generated image URL resolved to a private or invalid IP
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/7ac31172a33e3132.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/util/openai.go:969
data, err := io.ReadAll(io.LimitReader(resp.Body, maxGeneratedImageBytes+1))
if err != nil {
return nil, err
}
if len(data) > maxGeneratedImageBytes {
return nil, errors.New("generated image exceeds size limit")
}
return data, nil
}
func generatedImageHTTPClient() *http.Client {
return &http.Client{
Transport: &http.Transport{
Proxy: httpclient.ProxyFromEnvironment,
DialContext: generatedImageDialer().DialContext,
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if len(via) >= 3 || req.URL.Scheme != "https" {
return errors.New("generated image redirect is not allowed")
}
return CheckHostSSRF(req.URL.Hostname())
},
}
}
func generatedImageDialer() *net.Dialer {
return &net.Dialer{
Timeout: 30 * time.Second,
Control: func(_, address string, _ syscall.RawConn) error {
host, _, err := net.SplitHostPort(address)
if err != nil {
return err
}
ip, parseErr := netip.ParseAddr(host)
if parseErr != nil || isUnsafeGeneratedImageIP(ip.Unmap()) {
return errors.New("generated image URL resolved to a private or invalid IP")
}View on GitHub (pinned to 9f775e8a12)