{"record":{"id":"ca9a74ec865cd2a2","repo":"stalwartlabs/stalwart","slug":"storeevent-httpstoreerror","errorCode":"StoreEvent::HttpStoreError","errorMessage":"Failed to fetch HTTP list","messagePattern":"Failed to fetch HTTP list","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/store/src/backend/http/lookup.rs","lineNumber":110,"sourceCode":"        let time = Instant::now();\n        let agent = BROWSER_USER_AGENTS.choose(&mut rand::rng()).unwrap();\n        let response = self\n            .client\n            .get(&self.config.url)\n            .timeout(self.config.timeout)\n            .header(reqwest::header::USER_AGENT, *agent)\n            .send()\n            .await\n            .map_err(|err| {\n                trc::StoreEvent::HttpStoreError\n                    .into_err()\n                    .reason(err)\n                    .ctx(trc::Key::Url, self.config.url.to_compact_string())\n                    .details(\"Failed to build request\")\n            })?;\n\n        if !response.status().is_success() {\n            trc::bail!(\n                trc::StoreEvent::HttpStoreError\n                    .into_err()\n                    .ctx(trc::Key::Code, response.status().as_u16())\n                    .ctx(trc::Key::Url, self.config.url.to_compact_string())\n                    .ctx(trc::Key::Elapsed, time.elapsed())\n                    .details(\"Failed to fetch HTTP list\")\n            );\n        }\n\n        let bytes = response\n            .bytes_with_limit(self.config.max_size)\n            .await\n            .map_err(|err| {\n                trc::StoreEvent::HttpStoreError\n                    .into_err()\n                    .reason(err)\n                    .ctx(trc::Key::Url, self.config.url.to_compact_string())\n                    .ctx(trc::Key::Elapsed, time.elapsed())","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/stalwartlabs/stalwart/blob/e96200385781a6a9995a8b839ac27d6c75a983ee/crates/store/src/backend/http/lookup.rs#L92-L128","documentation":"The HTTP-backed store (used e.g. for IP blocklists/allowlists) refreshed its list by fetching a configured URL and the server returned a non-2xx status. The error carries the HTTP status code, URL and elapsed time as context. `try_refresh` bails so the caller (`refresh`) can keep the previous list or retry later.","triggerScenarios":"Periodic or manual refresh issues a GET to `self.config.url` and `response.status().is_success()` is false (404, 403, 500, etc.).","commonSituations":"Misconfigured list URL; the list provider requires an API key that's missing/expired; provider outage or rate-limiting; self-hosted list server down.","solutions":["Check the URL in the error context returns 200 when fetched manually (curl -I).","Fix the configured URL in config (http store url setting) if it is wrong or moved.","Add required authentication/credentials expected by the list provider.","Verify network/proxy reachability to the provider and check for rate limiting (status 429).","Confirm the list service is up; rely on the cached list until it recovers."],"exampleFix":"// before (config.toml)\nurl = \"http://example.com/blocklist.txt\"\n// after\nurl = \"https://lists.example.net/v2/blocklist.txt?apikey=YOUR_KEY\"","handlingStrategy":"retry","validationCode":"// before configuring, verify the URL serves the list\n// curl -fsS -o /dev/null -w '%{http_code}' \"$URL\"  # expect 200","typeGuard":null,"tryCatchPattern":"// retry transient failures, keep last-good list otherwise\nmatch refresh().await {\n    Err(err) if is_transient(&err) => schedule_retry(err, backoff),\n    Err(err) => log::warn!(\"keeping cached list: {err}\"),\n    Ok(_) => {},\n}","preventionTips":["Monitor the list URL with an uptime check.","Include API keys/credentials in store config where the provider requires them.","Keep the previously fetched list cached so failures degrade gracefully.","Pin list URLs to stable, versioned endpoints."],"tags":["http","network","store","configuration"],"backgroundTag":"http-error-response","analyzedSha":"e96200385781a6a9995a8b839ac27d6c75a983ee","analyzedAt":"2026-09-06T22:07:17.982Z","contentChangedAt":"2026-09-06T22:07:17.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}