Tencent/WeKnora · error

invalid SearXNG base_url: must not contain query or fragment

Error message

invalid SearXNG base_url: must not contain query or fragment

What it means

The SearXNG base_url contains a query string or fragment (?... or #...), which the validator rejects because the provider constructs its own request paths and parameters; user-supplied query/fragment would be lost or corrupt request construction.

Source

Thrown at internal/infrastructure/web_search/searxng.go:53

// ValidateSearxngBaseURL validates a SearXNG instance URL: must be a non-empty,
// absolute http(s) URL, and must pass the SSRF whitelist check. Shared between
// the service-layer parameter validation and the provider constructor so that
// "save" and "use" never disagree.
func ValidateSearxngBaseURL(rawURL string) error {
	base := strings.TrimSpace(rawURL)
	if base == "" {
		return fmt.Errorf("base_url is required for SearXNG provider")
	}
	parsed, err := url.Parse(base)
	if err != nil || parsed.Scheme == "" || parsed.Host == "" {
		return fmt.Errorf("invalid SearXNG base_url: must be an absolute http(s) URL")
	}
	if parsed.Scheme != "http" && parsed.Scheme != "https" {
		return fmt.Errorf("invalid SearXNG base_url scheme: %s", parsed.Scheme)
	}
	if parsed.RawQuery != "" || parsed.Fragment != "" {
		return fmt.Errorf("invalid SearXNG base_url: must not contain query or fragment")
	}
	if err := utils.ValidateURLForSSRF(base); err != nil {
		return fmt.Errorf("invalid SearXNG base_url: %w", err)
	}
	return nil
}

// NewSearxngProvider builds a SearXNG provider from tenant parameters.
func NewSearxngProvider(params types.WebSearchProviderParameters) (interfaces.WebSearchProvider, error) {
	base := strings.TrimSpace(params.BaseURL)
	if err := ValidateSearxngBaseURL(base); err != nil {
		return nil, err
	}

	client, err := NewSearchHTTPClient(defaultSearxngTimeout, params.ProxyURL)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Strip the query string and fragment, keeping only scheme://host[/basepath]
  2. Use the instance root URL, e.g. https://searx.example.com, not a search results link
  3. If the instance lives under a path, keep only the path: https://host/searxng
  4. Document/validate the field at save time to catch pasted search URLs

Example fix

// before
baseURL := "https://searx.example.com/search?q=test#top"
// after
baseURL := "https://searx.example.com"
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(baseURL)
if err == nil && (u.RawQuery != "" || u.Fragment != "") {
    return fmt.Errorf("base_url must not contain query or fragment: %s", baseURL)
}

Try / catch

if err := web_search.ValidateSearxngBaseURL(cfg.BaseURL); err != nil {
    if strings.Contains(err.Error(), "query or fragment") {
        return fmt.Errorf("use the instance base URL without ?query or #fragment")
    }
    return err
}

Prevention

When it happens

Trigger: NewSearxngProvider or save validation with base_url like "https://searx.example.com/search?q=x" or "https://searx.example.com/#results".

Common situations: Users pasting the full search results URL from their browser instead of the instance base URL, bookmark URLs containing anchors, deep links with session parameters.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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