Tencent/WeKnora · error
%s failed SSRF validation: %w
Error message
%s failed SSRF validation: %w
What it means
validateParserEngineOverrideURLs runs SSRF validation (secutils.ValidateURLForSSRF) on parser engine override URLs for each known outbound URL key. If a configured override URL fails SSRF checks (private/loopback/link-local addresses, disallowed schemes), it is rejected with this message naming the offending key.
Source
Thrown at internal/application/service/parser_url_security.go:29
"mineru_endpoint",
"mineru_vlm_server_url",
"odl_hybrid_url",
"paddleocr_vl_endpoint",
"paddleocr_vl_cloud_base_url",
}
// validateParserEngineOverrideURLs validates every parser override that can
// cause this process or the trusted DocReader service to make an outbound
// request. Per-upload overrides are included because API callers can provide
// the generic parser_engine_overrides map directly.
func validateParserEngineOverrideURLs(overrides map[string]string) error {
for _, key := range parserOutboundURLKeys {
rawURL := strings.TrimSpace(overrides[key])
if rawURL == "" {
continue
}
if err := secutils.ValidateURLForSSRF(rawURL); err != nil {
return fmt.Errorf("%s failed SSRF validation: %w", key, err)
}
}
return nil
}
View on GitHub (pinned to 988cbb0330)
Solutions
- Replace the override URL with a publicly reachable HTTPS endpoint that passes SSRF validation.
- If the target is legitimately internal, deploy an allowlist mechanism or run the validator with an approved internal-range policy instead of bypassing checks.
- Fix the scheme/typos: URLs must be absolute http(s) with a resolvable public host.
- Remove the empty/invalid override key so validation skips it.
Example fix
// before overrides["pdf_engine_url"] = "http://127.0.0.1:8080/parse" // after overrides["pdf_engine_url"] = "https://parser.example.com/parse"
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(rawURL)
if err != nil || (u.Scheme != "http" && u.Scheme != "https") { return fmt.Errorf("invalid override URL") }
if host := u.Hostname(); isPrivateOrLoopback(host) { return fmt.Errorf("override URL must be public") } Type guard
func isPublicHTTPURL(raw string) bool {
u, err := url.Parse(raw)
if err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Hostname() == "" { return false }
ip := net.ParseIP(u.Hostname())
return ip == nil || ip.IsPublic()
} Try / catch
if err := validateParserEngineOverrideURLs(overrides); err != nil {
// message names the offending key: reject that config field with 400
return fmt.Errorf("bad parser config: %w", err)
} Prevention
- Never point parser overrides at localhost/private ranges in shared environments
- Use absolute https:// URLs with public hostnames
- Validate override configs at save time, not only at request time
- Maintain an allowlist for legitimately internal parser endpoints
When it happens
Trigger: convert (or the config-validation path) receiving parser overrides where a key like an outbound URL contains http://localhost, 127.0.0.1, 169.254.169.254, 10.x/192.168.x addresses, or file:/other non-http schemes.
Common situations: Self-hosted setups pointing a parser engine at an internal service URL (localhost:8080) which the SSRF guard blocks; typos like 'htp://' or missing scheme; copying internal K8s service DNS into tenant-facing config; cloud metadata endpoint URLs pasted by mistake.
Related errors
- MinerU URL blocked by SSRF check: %v
- MCP service URL failed SSRF validation: %w
- ErrUnsafeOutboundURL
- join request not found
- failed to retrieve: %s
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/4fdf96635383bcd6.
Report an issue: GitHub.