{"record":{"id":"75fc37eae87c5c29","repo":"databendlabs/databend","slug":"failed-to-get-or-create-operator","errorCode":null,"errorMessage":"Failed to get or create operator: {}","messagePattern":"Failed to get or create operator: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/common/storage/src/operator.rs","lineNumber":87,"sourceCode":"\nstatic METRIC_OPENDAL_RETRIES_COUNT: LazyLock<FamilyCounter<Vec<(&'static str, String)>>> =\n    LazyLock::new(|| register_counter_family(\"opendal_retries_count\"));\n\n/// init_operator will init an opendal operator based on storage config.\npub fn init_operator(cfg: &StorageParams) -> Result<Operator> {\n    init_operator_with_policy_scope(cfg, EndpointPolicyScope::Trusted)\n}\n\n/// init_operator_with_policy_scope will init an opendal operator with an\n/// explicit endpoint egress policy scope.\npub fn init_operator_with_policy_scope(\n    cfg: &StorageParams,\n    endpoint_policy_scope: EndpointPolicyScope,\n) -> Result<Operator> {\n    let cache = get_operator_cache();\n    cache\n        .get_or_create(cfg, endpoint_policy_scope)\n        .map_err(|e| Error::other(anyhow!(\"Failed to get or create operator: {}\", e)))\n}\n\n/// init_operator_uncached will init an opendal operator without caching.\n/// This function creates a new operator every time it's called.\npub(crate) fn init_operator_uncached(\n    cfg: &StorageParams,\n    endpoint_policy_scope: EndpointPolicyScope,\n) -> Result<Operator> {\n    let op = match &cfg {\n        StorageParams::Azblob(cfg) => build_operator(\n            init_azblob_operator(cfg)?,\n            cfg.network_config.as_ref(),\n            endpoint_policy_scope,\n        )?,\n        StorageParams::Fs(cfg) => {\n            build_operator(init_fs_operator(cfg)?, None, endpoint_policy_scope)?\n        }\n        StorageParams::Gcs(cfg) => build_operator(","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/common/storage/src/operator.rs#L69-L105","documentation":"init_operator_with_policy_scope consults the process-wide operator cache (get_operator_cache().get_or_create) keyed by StorageParams and policy scope; this error wraps any failure of that construction. It is the common funnel through which storage misconfigurations surface when initializing an Operator for tables, stages, or attach requests.","triggerScenarios":"Calling init_operator, init_stage_operator, build_attach_table_request, or executor bind_create_table/bind_attach_table with a StorageParams whose endpoint is unreachable, credentials invalid, bucket missing, or whose opendal config fails validation during operator build.","commonSituations":"Wrong S3 endpoint/region in the databend query config; expired or incorrect access keys; DNS failure resolving the storage endpoint; operator cache build racing with config reload.","solutions":["Read the wrapped inner error ({}) — it names the concrete opendal failure (config invalid, connection refused, auth).","Validate the [storage] section of the query config: endpoint, bucket, root, credentials.","Test connectivity to the storage endpoint from the node (curl the endpoint / aws s3 ls).","Restart/retry after fixing config; operators are cached, so a config fix requires rebuilding the operator (process restart or cache invalidation)."],"exampleFix":"// before (config)\n[storage]\ntype = \"s3\"\n[storage.s3]\nbucket = \"\"\n// after\n[storage.s3]\nbucket = \"my-bucket\"\nendpoint_url = \"https://s3.us-east-1.amazonaws.com\"","handlingStrategy":"try-catch","validationCode":"// Rust: sanity-check StorageParams before initializing\nif let StorageParams::S3(cfg) = &storage_params {\n    assert!(!cfg.bucket.is_empty(), \"s3 bucket required\");\n    assert!(!cfg.endpoint_url.is_empty(), \"s3 endpoint required\");\n}","typeGuard":null,"tryCatchPattern":"match init_operator(&storage_params).await {\n    Ok(op) => op,\n    Err(e) => {\n        tracing::error!(\"operator init failed: {e}\");\n        return Err(e);\n    }\n}","preventionTips":["Validate the [storage] config at startup with databend-query's config check","Test endpoint connectivity/DNS from every node before rolling out config","Remember operators are cached — restart or invalidate cache after config changes"],"tags":["rust","opendal","storage","databend"],"backgroundTag":"missing-required-config","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"}