crowdsecurity/crowdsec · error

unable to parse url '%s': %s

Error message

unable to parse url '%s': %s

What it means

url.Parse rejected the reconstructed client URI (clientURI) while building a ParsedRequest for appsec evaluation. The URI came from the bouncer's forwarded request data, so this means the bouncer sent a malformed request line/URI that Go's URL parser refuses. Note the error uses %s, so it does not unwrap.

Source

Thrown at pkg/appsec/request.go:444

	transactionID := r.Header.Get(TransactionIDHeaderName)
	if transactionID == "" {
		transactionID = uuid.New().String()
	}

	if httpVersion := r.Header.Get(HTTPVersionHeaderName); httpVersion != "" {
		applyHTTPVersion(r, httpVersion, logger)
	} else {
		logger.Debugf("missing '%s' header", HTTPVersionHeaderName)
	}

	for _, h := range forwardedHeaders {
		delete(r.Header, h)
	}

	parsedURL, err := url.Parse(clientURI)
	if err != nil {
		return ParsedRequest{}, fmt.Errorf("unable to parse url '%s': %s", clientURI, err)
	}

	originalHTTPRequest := r.Clone(r.Context())
	originalHTTPRequest.Body = io.NopCloser(bytes.NewBuffer(body))
	originalHTTPRequest.RemoteAddr = clientIP
	originalHTTPRequest.RequestURI = clientURI
	originalHTTPRequest.Method = clientMethod
	originalHTTPRequest.Host = clientHost
	originalHTTPRequest.URL = parsedURL
	if userAgent != "" {
		// Override the UA in the original request — this is what the WAF engine sees.
		originalHTTPRequest.Header.Set("User-Agent", userAgent)
		r.Header.Set("User-Agent", userAgent)
	} else {
		// No forwarded UA: drop any UA the remediation layer added, on both copies.
		originalHTTPRequest.Header.Del("User-Agent")
		r.Header.Del("User-Agent")
	}

View on GitHub (pinned to 909b515798)

Solutions

  1. Inspect the bouncer→appsec channel: the forwarded URL contains characters or structure Go rejects (bad percent-encoding, control chars)
  2. Update the bouncer if a known forwarding bug exists
  3. Isolate the offending request via appsec logs and reproduce it against the origin
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pkg/appsec/request.go:444 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/563b2998550d95f6. Report an issue: GitHub.