{"record":{"id":"4807f0f33c585de1","repo":"crowdsecurity/crowdsec","slug":"while-checking-if-we-should-force-pull-blocklist","errorCode":null,"errorMessage":"while checking if we should force pull blocklist %s: %w","messagePattern":"while checking if we should force pull blocklist (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apiserver/apic.go","lineNumber":951,"sourceCode":"\n\treturn false, nil\n}\n\nfunc (a *apic) updateBlocklist(ctx context.Context, client *apiclient.ApiClient, blocklist *modelscapi.BlocklistLink, addCounters map[string]map[string]int, forcePull bool) error {\n\tif blocklist.Scope == nil {\n\t\tlog.Warningf(\"blocklist has no scope\")\n\t\treturn nil\n\t}\n\n\tif blocklist.Duration == nil {\n\t\tlog.Warningf(\"blocklist has no duration\")\n\t\treturn nil\n\t}\n\n\tif !forcePull {\n\t\t_forcePull, err := a.ShouldForcePullBlocklist(ctx, blocklist)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"while checking if we should force pull blocklist %s: %w\", *blocklist.Name, err)\n\t\t}\n\n\t\tforcePull = _forcePull\n\t}\n\n\tblocklistConfigItemName := fmt.Sprintf(\"blocklist:%s:last_pull\", *blocklist.Name)\n\n\tvar (\n\t\tlastPullTimestamp string\n\t\terr               error\n\t)\n\n\tif !forcePull {\n\t\tlastPullTimestamp, err = a.dbClient.GetConfigItem(ctx, blocklistConfigItemName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"while getting last pull timestamp for blocklist %s: %w\", *blocklist.Name, err)\n\t\t}\n\t}","sourceCodeStart":933,"sourceCodeEnd":969,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/apiserver/apic.go#L933-L969","documentation":"updateBlocklist wraps errors from ShouldForcePullBlocklist, which decides whether the blocklist must be re-pulled by checking stored alert/decision freshness. Any non-NotFound DB error from those checks surfaces through this message, with the blocklist name in the text.","triggerScenarios":"UpdateBlocklists iterates subscribed blocklists; for one of them ShouldForcePullBlocklist returns an error because the alert or decision lookup failed at the DB layer.","commonSituations":"Database outage during a pull cycle, SQLite lock contention, blocklist name referencing stale data after manual DB cleanup.","solutions":["Check the inner error and DB status (`cscli db doctor`).","Restart crowdsec to reset DB connections after an outage.","Enable WAL mode for SQLite.","As a workaround, force a pull (`cscli capi pull` / next cycle) once DB is healthy."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// verify DB reachable: cscli db doctor","typeGuard":null,"tryCatchPattern":"if !forcePull {\n    _forcePull, err := a.ShouldForcePullBlocklist(ctx, blocklist)\n    if err != nil {\n        log.Warnf(\"force-pull check failed (%v), defaulting to force pull\", err)\n        forcePull = true\n    } else {\n        forcePull = _forcePull\n    }\n}","preventionTips":["Fall back to forcePull=true on check failure so pulls stay correct.","Monitor DB health on the LAPI host.","Don't manually delete alert/decision rows for subscribed blocklists."],"tags":["database","blocklist","capi","pull"],"backgroundTag":"database-query-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}