{"record":{"id":"8e2609dca6749fde","repo":"databendlabs/databend","slug":"err-8e2609","errorCode":null,"errorMessage":"{err}","messagePattern":"\\{err\\}","errorType":"exception","errorClass":"Unexpected","httpStatus":null,"severity":"error","filePath":"src/common/storage/src/http_client.rs","lineNumber":156,"sourceCode":"                // hostname endpoints (closing the DNS-rebinding TOCTOU\n                // window) and IP-literal endpoints (closing a 30x\n                // bounce-to-internal bypass), since check_url_with_dns now\n                // populates resolved_addrs for IP literals as well.\n                let mut builder = storage_http_client_builder()\n                    .http1_only()\n                    .use_native_tls()\n                    .dns_resolver(get_global_hickory_resolver())\n                    .redirect(reqwest::redirect::Policy::none())\n                    .pool_max_idle_per_host(self.pool_max_idle_per_host)\n                    .connect_timeout(Duration::from_secs(self.connect_timeout))\n                    .resolve_to_addrs(&host, resolved_addrs);\n\n                if self.keepalive != 0 {\n                    builder = builder.tcp_keepalive(Duration::from_secs(self.keepalive));\n                }\n\n                builder.build().map_err(|err| {\n                    opendal::Error::new(opendal::ErrorKind::Unexpected, err.to_string())\n                })\n            })?\n            .clone();\n\n        Ok(client)\n    }\n\n    async fn check_endpoint_cached(&self, url: &Url) -> opendal::Result<EndpointUrlCheck> {\n        let host = url.host_str().unwrap_or_default().to_ascii_lowercase();\n        let port = url.port_or_known_default().unwrap_or_default();\n        let key = EndpointCheckCacheKey {\n            scheme: url.scheme().to_ascii_lowercase(),\n            host,\n            port,\n        };\n\n        {\n            let mut cache = self.checked_endpoints.lock().unwrap();","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/common/storage/src/http_client.rs#L138-L174","documentation":"Raised in `HttpClient::client_for_checked_endpoint` when the `reqwest` client cannot be built from the configured TLS/timeout/keepalive options. The reqwest builder error is converted into an `opendal::Error` with kind Unexpected, meaning the HTTP client itself could not be constructed (not that a request failed).","triggerScenarios":"Calling `HttpClient::fetch` where the resolved config produces an invalid client: e.g. an invalid `tcp_keepalive` duration, a TLS config referencing missing certificate/key files or an unsupported TLS backend, or a reqwest feature (like rustls) not compiled in for the requested scheme.","commonSituations":"Deployment config pointing at certificates that don't exist on the node, mismatched TLS feature flags between crates, or an OS/env where the native-tls backend is unavailable.","solutions":["Read the wrapped `err.to_string()` — it names the exact reqwest builder failure (TLS cert path, keepalive, etc.).","Verify configured TLS certificate/key file paths exist and are readable on the node.","Check the storage config (timeout, keepalive, TLS settings) for invalid values and fix them.","Ensure the reqwest feature set (native-tls vs rustls) matches the deployed environment; rebuild with the right features."],"exampleFix":"// before: cert path wrong in config\nHttpClient::new().with_tls_files(\"/missing/cert.pem\", \"/missing/key.pem\")?\n// after\nHttpClient::new().with_tls_files(\"/etc/databend/cert.pem\", \"/etc/databend/key.pem\")?","handlingStrategy":"validation","validationCode":"fn tls_files_exist(cert: &str, key: &str) -> bool {\n    std::path::Path::new(cert).is_file() && std::path::Path::new(key).is_file()\n}","typeGuard":"fn client_config_ok(cfg: &StorageHttpConfig) -> bool {\n    cfg.cert_file.as_deref().map_or(true, |c| std::path::Path::new(c).is_file())\n        && cfg.key_file.as_deref().map_or(true, |k| std::path::Path::new(k).is_file())\n}","tryCatchPattern":"match client.fetch(url, range).await {\n    Ok(r) => r,\n    Err(e) if e.to_string().contains(\"Unexpected\") => {\n        // client construction failed; check TLS config before retrying\n        return Err(anyhow!(\"http client init failed: {e}\"));\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Verify TLS cert/key paths exist and are readable on every node before startup.","Keep reqwest TLS features consistent across the workspace build.","Sanity-check timeout/keepalive config values at load time."],"tags":["http","client-init","opendal","tls"],"backgroundTag":"http-request-failed","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}