Tencent/WeKnora · error

base_url SSRF validation failed: %w

Error message

base_url SSRF validation failed: %w

What it means

ValidateConnectorBaseURL runs utils.ValidateURLForSSRF on the connector's base_url to block requests to loopback/link-local/internal addresses (SSRF protection). This error wraps that underlying failure, so the message includes the specific reason the URL was rejected (private IP, loopback, disallowed scheme, etc.).

Source

Thrown at internal/datasource/httpclient.go:23

	"net/http"
	"strings"
	"time"

	"github.com/Tencent/WeKnora/internal/utils"
)

// ValidateConnectorBaseURL checks a connector API base URL against the SSRF policy.
// Empty rawURL is allowed; callers apply their own default before issuing requests.
func ValidateConnectorBaseURL(rawURL string) error {
	url := strings.TrimSpace(rawURL)
	if url == "" {
		return nil
	}
	if !strings.Contains(url, "://") {
		url = "https://" + url
	}
	if err := utils.ValidateURLForSSRF(url); err != nil {
		return fmt.Errorf("base_url SSRF validation failed: %w", err)
	}
	return nil
}

// NewConnectorHTTPClient returns an HTTP client with redirect and dial-time SSRF guards.
func NewConnectorHTTPClient(timeout time.Duration) *http.Client {
	cfg := utils.DefaultSSRFSafeHTTPClientConfig()
	cfg.Timeout = timeout
	return utils.NewSSRFSafeHTTPClient(cfg)
}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Use the public HTTPS endpoint URL for the service instead of localhost/internal addresses.
  2. If the deployment is intentionally private, add the hostname to SSRF_WHITELIST per the validation policy.
  3. Read the wrapped %w cause to see exactly which rule failed (scheme, IP range, port) and correct that aspect of the URL.

Example fix

// before
"base_url": "http://127.0.0.1:8080"
// after
"base_url": "https://open.example-service.com"  // or add host to SSRF_WHITELIST
Defensive patterns

Strategy: validation

Validate before calling

u, _ := url.Parse(baseURL)
ip := net.ParseIP(u.Hostname())
if ip != nil && (ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast()) {
    return errors.New("base_url points at a private/loopback address")
}

Type guard

func isPublicHTTPS(u *url.URL) bool {
    return (u.Scheme == "https" || u.Scheme == "http") &&
        net.ParseIP(u.Hostname()) == nil // not a raw IP
}

Try / catch

if err := datasource.ValidateConnectorBaseURL(baseURL); err != nil {
    if strings.Contains(err.Error(), "SSRF") {
        // guide user to use a public URL or SSRF_WHITELIST
    }
    return err
}

Prevention

When it happens

Trigger: Calling any connector init/validation that runs parseFeishuConfig, newClient, parseIMAConfig, or parseYuqueConfig with a base_url pointing at localhost, 127.0.0.1, 169.254.x, or another internal address not on the SSRF whitelist.

Common situations: Self-hosted/private deployments where the connector genuinely targets an internal service; typo'd base_url like http://localhost:3000; Docker environments where internal hostnames resolve to blocked ranges.

Related errors


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