databendlabs/databend · warning

S3 params must remain S3

Error message

S3 params must remain S3

What it means

This unreachable!() lives in a test in storage_params.rs that calls without_credentials() on a StorageParams::S3 and asserts the result is still StorageParams::S3. If the credential-stripping function ever changed the variant type (e.g. converting S3 params to another storage flavor or dropping them), the pattern match fails and the test panics with 'S3 params must remain S3'. It guards the contract that removing credentials never alters the storage variant.

Solutions

  1. Ensure without_credentials() rebuilds StorageParams::S3 with the same location fields minus credentials
  2. Keep the S3-specific fields (endpoint_url, region, bucket, root, enable_virtual_host_style) intact when stripping secrets
  3. Run the storage_params tests (`cargo test -p meta-app-storage -- storage_params`) after changes

Example fix

// before
pub fn without_credentials(&self) -> StorageParams { /* returns wrong variant */ }
// after
pub fn without_credentials(&self) -> StorageParams {
    match self {
        StorageParams::S3(loc) => StorageParams::S3(loc.without_credentials()),
        other => other.clone(),
    }
}
Defensive patterns

Strategy: validation

Validate before calling

assert!(matches!(params, StorageParams::S3(_)), "without_credentials requires S3 params");

Try / catch

let StorageParams::S3(loc) = params.without_credentials() else {
    log::error!("without_credentials changed variant");
    return Err(ErrorCode::InternalError("S3 params must remain S3"));
};

Prevention

When it happens

Trigger: Modifying StorageParams::without_credentials or the S3 storage-param types so it no longer returns a StorageParams::S3 variant, then running the storage-params tests.

Common situations: Refactors of StorageParams (adding new storage backends, changing without_credentials to a generic transform); accidental use of a constructor that wraps S3 in another enum variant.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/eb215389908602fa. Report an issue: GitHub.

Appendix: source

Thrown at src/meta/app-storage/src/storage_params.rs:1143

        let params = StorageParams::S3(StorageS3Config {
            endpoint_url: "http://provider.example:9000".to_string(),
            region: "provider-region".to_string(),
            bucket: "provider-bucket".to_string(),
            root: "provider/root".to_string(),
            enable_virtual_host_style: true,
            access_key_id: "provider-key".to_string(),
            secret_access_key: "provider-secret".to_string(),
            security_token: "provider-token".to_string(),
            master_key: "provider-master-key".to_string(),
            role_arn: "provider-role".to_string(),
            external_id: "provider-external-id".to_string(),
            disable_credential_loader: true,
            allow_credential_chain: Some(true),
            ..Default::default()
        });

        let StorageParams::S3(location) = params.without_credentials() else {
            unreachable!("S3 params must remain S3");
        };
        assert_eq!("http://provider.example:9000", location.endpoint_url);
        assert_eq!("provider-region", location.region);
        assert_eq!("provider-bucket", location.bucket);
        assert_eq!("provider/root", location.root);
        assert!(location.enable_virtual_host_style);
        assert!(location.access_key_id.is_empty());
        assert!(location.secret_access_key.is_empty());
        assert!(location.security_token.is_empty());
        assert!(location.master_key.is_empty());
        assert!(location.role_arn.is_empty());
        assert!(location.external_id.is_empty());
        assert!(!location.disable_credential_loader);
        assert_eq!(None, location.allow_credential_chain);
    }
}

View on GitHub (pinned to 288d84d76e)