crowdsecurity/crowdsec · critical

while parsing '%s': %w

Error message

while parsing '%s': %w

What it means

NewAPIC parses config.Credentials.URL with net/url.Parse and wraps failures with this message. It means the central API URL string in the crowdsec configuration is not a parseable absolute URL, so the CAPI client cannot be constructed and startup aborts.

Source

Thrown at pkg/apiserver/apic.go:224

		pullInterval:              pullIntervalDefault,
		pullIntervalFirst:         randomDuration(pullIntervalDefault, pullIntervalDelta),
		pushInterval:              pushIntervalDefault,
		pushIntervalFirst:         randomDuration(pushIntervalDefault, pushIntervalDelta),
		metricsInterval:           metricsIntervalDefault,
		metricsIntervalFirst:      randomDuration(metricsIntervalDefault, metricsIntervalDelta),
		usageMetricsInterval:      usageMetricsInterval,
		usageMetricsIntervalFirst: randomDuration(usageMetricsInterval, usageMetricsIntervalDelta),
		usageMetricsBatchBytes:    usageMetricsBatchBytes,
		isPulling:                 make(chan bool, 1),
		whitelists:                apicWhitelist,
		pullBlocklists:            *config.PullConfig.Blocklists,
		pullCommunity:             *config.PullConfig.Community,
		shareSignals:              *config.Sharing,
	}

	apiURL, err := url.Parse(config.Credentials.URL)
	if err != nil {
		return nil, fmt.Errorf("while parsing '%s': %w", config.Credentials.URL, err)
	}

	papiURL, err := url.Parse(config.Credentials.PapiURL)
	if err != nil {
		return nil, fmt.Errorf("while parsing '%s': %w", config.Credentials.PapiURL, err)
	}

	ret.apiClient = apiclient.NewClient(&apiclient.Config{
		MachineID:      config.Credentials.Login,
		Password:       strfmt.Password(config.Credentials.Password),
		URL:            apiURL,
		PapiURL:        papiURL,
		VersionPrefix:  "v3",
		UpdateScenario: ret.FetchScenariosListFromDB,
		TokenSave: func(ctx context.Context, token string) error {
			return dbClient.SaveAPICToken(ctx, token)
		},
	})

View on GitHub (pinned to 909b515798)

Solutions

  1. Open the crowdsec config and check the api.server/capi credentials URL for stray characters, whitespace, or unquoted values
  2. Quote the URL in YAML (url: "https://api.crowdsec.net/") to avoid parser mangling
  3. Test the string with a quick url.Parse snippet or echo it to spot invisible characters
  4. Re-download/re-generate credentials (cscli capi register or reinstall defaults) if hand-editing broke them

Example fix

// before (config.yaml)
api_url: http://api.crowdsec.net/
// after (quoted, valid)
api_url: "https://api.crowdsec.net/"
Defensive patterns

Strategy: validation

Validate before calling

func validURL(s string) bool {
	u, err := url.Parse(s)
	return err == nil && u.Scheme != "" && u.Host != ""
}
if !validURL(cfg.Credentials.URL) {
	return errors.New("credentials.URL is not a valid absolute URL")
}

Try / catch

apiURL, err := url.Parse(config.Credentials.URL)
if err != nil {
	return nil, fmt.Errorf("while parsing '%s': %w", config.Credentials.URL, err)
}

Prevention

When it happens

Trigger: url.Parse(config.Credentials.URL) errors at crowdsec startup — e.g. URL contains control characters, an invalid percent-encoding, or a malformed scheme that url.Parse rejects (note: url.Parse accepts many odd strings, so this usually means genuinely broken characters).

Common situations: Copy-pasted credentials URL with trailing spaces/newlines or smart quotes; YAML folding mangled the URL with special characters (e.g. '#', ':' breaking quoting); hand-edited config.yaml with an unquoted URL containing '://' fragments; env interpolation produced an empty or garbage value.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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