crowdsecurity/crowdsec · error

invalid Loki URL %q: %w

Error message

invalid Loki URL %q: %w

What it means

updateURI re-parses the current query_range URI to append new start/next parameters when paginating through results. If the stored URI cannot be parsed by url.Parse, this error wraps the cause and aborts the query loop.

Source

Thrown at pkg/acquisition/modules/loki/internal/lokiclient/loki_client.go:54

	Query      string
	Headers    map[string]string

	Username string
	Password string

	Since time.Duration
	Until time.Duration

	FailMaxDuration time.Duration

	DelayFor int
	Limit    int
}

func updateURI(uri string, lq LokiQueryRangeResponse, infinite bool) (string, error) {
	u, err := url.Parse(uri)
	if err != nil {
		return "", fmt.Errorf("invalid Loki URL %q: %w", uri, err)
	}
	queryParams := u.Query()

	var maxTS time.Time
	for _, stream := range lq.Data.Result {
		for _, entry := range stream.Entries {
			if entry.Timestamp.After(maxTS) {
				maxTS = entry.Timestamp
			}
		}
	}

	if !maxTS.IsZero() {
		// +1 the last timestamp to avoid getting the same result again.
		queryParams.Set("start", strconv.FormatInt(maxTS.UnixNano()+1, 10))
	}
	// When maxTS.IsZero() (no results), keep the existing start to avoid
	// re-fetching already-processed logs. Only end is moved forward below.

View on GitHub (pinned to 909b515798)

Solutions

  1. Fix the datasource URL in the DSN so it is a valid absolute URL (scheme://host:port/path?params)
  2. Percent-encode special characters ('%' as '%25', spaces as '%20')
  3. Verify with a quick url.Parse in Go or a browser that the URL is well formed

Example fix

// before
loki://localhost:3100/loki/api/v1/query_range?query={job="app"}
// after
loki://localhost:3100/loki/api/v1/query_range?query=%7Bjob%3D%22app%22%7D
Defensive patterns

Strategy: validation

Validate before calling

if _, err := url.Parse(dsnURL); err != nil {
    return fmt.Errorf("datasource URL invalid: %w", err)
}

Prevention

When it happens

Trigger: The URI constructed from the DSN (getURLFor + query params) is malformed — e.g. invalid percent-escapes or a corrupted URL string built from a bad datasource config.

Common situations: Malformed DSN host with stray characters; control characters or unencoded '%' in query 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 crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/25f25d0464440954. Report an issue: GitHub.