Tencent/WeKnora · error

MinerU URL blocked by SSRF check: %v

Error message

MinerU URL blocked by SSRF check: %v

What it means

validateMinerUOutboundURL runs the configured MinerU endpoint through utils.ValidateURLForSSRF before any outbound request is made. If the URL resolves to a loopback, link-local, private, or otherwise forbidden address (or uses a disallowed scheme), the converter refuses to call it and reports this error. It is a deliberate security guard against SSRF attacks, not a MinerU failure.

Source

Thrown at internal/infrastructure/docparser/mineru_converter.go:356

	}

	return refs, mdContent
}

// logMinerUResponseStructure logs the structure of the MinerU API response.
func (c *MinerUReader) logMinerUResponseStructure(obj interface{}, prefix string) {
	logResponseStructure("MinerU", obj, prefix)
}

// validateMinerUOutboundURL rejects MinerU endpoints that would reach private
// or otherwise restricted hosts when parsed or probed from the app server.
func validateMinerUOutboundURL(rawURL string) error {
	rawURL = strings.TrimSpace(rawURL)
	if rawURL == "" {
		return nil
	}
	if err := utils.ValidateURLForSSRF(rawURL); err != nil {
		return fmt.Errorf("MinerU URL blocked by SSRF check: %v", err)
	}
	return nil
}

// PingMinerU checks if the self-hosted MinerU service is reachable.
func PingMinerU(endpoint string) (bool, string) {
	endpoint = strings.TrimRight(endpoint, "/")
	if endpoint == "" {
		return false, "未配置 MinerU 端点"
	}
	if err := validateMinerUOutboundURL(endpoint); err != nil {
		return false, err.Error()
	}
	client := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{
		Timeout:      5 * time.Second,
		MaxRedirects: 5,
	})
	resp, err := client.Get(endpoint + "/docs")

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Set the MinerU endpoint to the real internal/external service hostname (not loopback/link-local), e.g. http://mineru.internal:8000
  2. If a private-network MinerU is intentional, relax the SSRF allowlist configuration explicitly (allowed CIDRs) rather than bypassing the check
  3. Confirm the scheme is http or https; strip whitespace (the validator trims, but empty URLs pass silently as nil)
  4. If this error appears in unit tests, it is expected behavior — use a public-shaped test URL or adjust the test

Example fix

// before
endpoint := "http://127.0.0.1:8888"
// after
endpoint := os.Getenv("MINERU_ENDPOINT") // e.g. "http://mineru.internal.svc:8888"
Defensive patterns

Strategy: validation

Validate before calling

if err := validateMinerUOutboundURL(cfg.Endpoint); err != nil {
    return nil, fmt.Errorf("invalid MinerU endpoint at startup: %w", err)
}

Type guard

func isSSRFBlocked(err error) bool {
    return err != nil && strings.Contains(err.Error(), "blocked by SSRF check")
}

Try / catch

res, err := reader.Read(ctx, req)
if isSSRFBlocked(err) {
    logger.Error("MinerU endpoint rejected by SSRF guard; fix configuration, do not bypass")
    return nil, err
}

Prevention

When it happens

Trigger: Calling Read or PingMinerU with a MinerU endpoint that is localhost/127.0.0.1, ::1, 169.254.x.x, 10.x/172.16-31.x/192.168.x, a metadata IP, or a non-http(s) scheme; also hit by the test TestValidateMinerUOutboundURL_RejectsLoopback.

Common situations: Developers pointing MinerU config at a local self-hosted service (http://localhost:8080) in an environment where the SSRF guard blocks loopback; misconfigured env var left as a development URL in production; endpoint set to a metadata service address.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/8654a71ae1751cd9. Report an issue: GitHub.