crowdsecurity/crowdsec · error
blocklist URL is nil
Error message
blocklist URL is nil
What it means
GetDecisionsFromBlocklist fetches community-blocklist content from a BlocklistLink; the URL to fetch lives in blocklist.URL. If the URL pointer is nil the blocklist entry has no source address, and fetching is impossible, so the function returns this error early.
Source
Thrown at pkg/apiclient/decisions_service.go:177
partialDecisions[idx] = &models.Decision{
Scenario: &scenarioDeleted,
Scope: decisionsGroup.Scope,
Type: new(types.DecisionTypeBan),
Value: &decision,
Duration: &durationDeleted,
Origin: new(types.CAPIOrigin),
}
}
v2Decisions.Deleted = append(v2Decisions.Deleted, partialDecisions...)
}
return &v2Decisions, resp, nil
}
func (*DecisionsService) GetDecisionsFromBlocklist(ctx context.Context, blocklist *modelscapi.BlocklistLink, lastPullTimestamp string) ([]*models.Decision, bool, error) {
if blocklist.URL == nil {
return nil, false, errors.New("blocklist URL is nil")
}
log.Debugf("Fetching blocklist %s", *blocklist.URL)
client := http.Client{}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, *blocklist.URL, http.NoBody)
if err != nil {
return nil, false, err
}
if lastPullTimestamp != "" {
req.Header.Set("If-Modified-Since", lastPullTimestamp)
}
log.Debugf("[URL] %s %s", req.Method, req.URL)
// we don't use client_http Do method because we need the reader and is not provided.View on GitHub (pinned to 909b515798)
Solutions
- Skip blocklists with nil URL before calling: if bl.URL != nil { ... }
- Update crowdsec so the CAPI client parses the blocklist metadata correctly and filters null-URL entries.
- Log and continue on this error for individual blocklists instead of aborting the whole pull.
Example fix
// before
for _, bl := range blocklists {
decisions, changed, err := svc.GetDecisionsFromBlocklist(ctx, bl, lastPull)
// after
for _, bl := range blocklists {
if bl.URL == nil {
log.Warnf("blocklist %s has no URL, skipping", bl.Name)
continue
}
decisions, changed, err := svc.GetDecisionsFromBlocklist(ctx, bl, lastPull) Defensive patterns
Strategy: validation
Validate before calling
if blocklist == nil || blocklist.URL == nil || *blocklist.URL == "" {
return nil // skip
} Type guard
func hasURL(b *modelscapi.BlocklistLink) bool {
return b != nil && b.URL != nil && *b.URL != ""
} Try / catch
decisions, changed, err := svc.GetDecisionsFromBlocklist(ctx, bl, ts)
if err != nil {
log.Warnf("blocklist fetch failed: %v", err)
continue
} Prevention
- Filter blocklist links for non-nil URLs before iterating.
- Keep crowdsec updated so CAPI blocklist metadata parsing stays current.
- Treat per-blocklist errors as non-fatal and continue the pull.
When it happens
Trigger: Calling GetDecisionsFromBlocklist with a BlocklistLink parsed from CAPI metadata whose url field was absent/JSON null, or a hand-constructed BlocklistLink without setting URL.
Common situations: CAPI returns a blocklist entry with a null url (e.g. malformed or new link type not yet populated), older CAPI response formats, custom code iterating all blocklist links including ones without URLs.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- while saving alert from %s: %w
- while checking if we should force pull blocklist %s: %w
- while getting decisions from blocklist %s: %w
- while saving alert from blocklist %s: %w
- pull already in progress
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/a3704c4ffc774d8c.
Report an issue: GitHub.