crowdsecurity/crowdsec · error

failed to build request: %w

Error message

failed to build request: %w

What it means

FetchContent wraps the error from Downloader.urlTo when building the URL for a hub content file fails. Like the index variant, this is a request-construction failure before any network I/O, with the root cause preserved via %w.

Source

Thrown at pkg/cwhub/download.go:92

		WithLogger(logger.WithField("url", url)).
		BeforeRequest(func(_ *http.Request) {
			fmt.Fprintln(os.Stdout, "Downloading " + destPath)
		}).
		Download(ctx, url.String())
	if err != nil {
		return false, err
	}

	return downloaded, nil
}

// FetchContent downloads the content to the specified path, through a temporary file
// to avoid partial downloads.
// If the hash does not match, it will not overwrite and log a warning.
func (d *Downloader) FetchContent(ctx context.Context, remotePath, destPath, wantHash string, logger *logrus.Logger) (downloaded bool, url string, err error) {
	u, err := d.urlTo(remotePath)
	if err != nil {
		return false, "", fmt.Errorf("failed to build request: %w", err)
	}

	downloaded, err = downloader.
		New().
		WithHTTPClient(HubClient).
		ToFile(destPath).
		WithETagFn(downloader.SHA256).
		WithMakeDirs(true).
		WithLogger(logger.WithField("url", url)).
		CompareContent().
		VerifyHash("sha256", wantHash).
		Download(ctx, u.String())

	var hasherr downloader.HashMismatchError

	switch {
	case errors.As(err, &hasherr):
		logger.Warnf("%s. The index file is outdated, please run 'cscli hub update' and try again", err.Error())

View on GitHub (pinned to 909b515798)

Solutions

  1. Verify the hub api_url in the crowdsec configuration is a valid URL
  2. Re-run `cscli hub update` after fixing the config
  3. If constructing a Downloader in code, ensure the base URL field is populated before calling FetchContent

Example fix

// before
d := &Downloader{} // base URL never set
_, _, err := d.FetchContent(ctx, path, dest, hash, logger)
// after
d, err := NewDownloader(hubURL, "")
if err != nil { return err }
_, _, err = d.FetchContent(ctx, path, dest, hash, logger)
Defensive patterns

Strategy: try-catch

Validate before calling

if u, err := url.Parse(cfg.HubAPIURL); err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("hub api_url %q is not a valid absolute URL", cfg.HubAPIURL)
}

Try / catch

downloaded, _, err := d.FetchContent(ctx, remote, dest, hash, logger)
if err != nil {
    var urlErr *url.Error
    if errors.As(err, &urlErr) {
        logger.Errorf("cannot build hub request: %v — check hub URL config", err)
        return
    }
    return err
}

Prevention

When it happens

Trigger: Calling Downloader.FetchContent with a remotePath that, combined with the downloader base URL, fails urlTo — typically because the downloader's base URL is empty or invalid.

Common situations: Hub URL unset in configuration, corrupted config after upgrade, or programmatically constructing a Downloader without setting its base URL.

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/bbca22ce9ed9507c. Report an issue: GitHub.