risingwavelabs/risingwave · critical

Passing s3-compatible is not supported, please modify the en

Error message

Passing s3-compatible is not supported, please modify the environment variable and pass in s3.

What it means

build_remote_object_store panics when a remote URL uses the legacy s3-compatible:// scheme. The s3-compatible mode has been unified into the s3 mode; s3 now handles compatible endpoints via RW_S3_ENDPOINT plus AWS credential/region environment variables.

Source

Thrown at src/object_store/src/object/mod.rs:1011

                )
                .unwrap()
                .monitored(metrics, config),
            )
        }
        fs if fs.starts_with("fs://") => {
            let fs = fs.strip_prefix("fs://").unwrap();
            ObjectStoreImpl::Opendal(
                OpendalObjectStore::new_fs_engine(fs.to_owned(), config.clone(), metrics.clone())
                    .unwrap()
                    .monitored(metrics, config),
            )
        }

        s3_compatible if s3_compatible.starts_with("s3-compatible://") => {
            tracing::error!("The s3 compatible mode has been unified with s3.");
            tracing::error!("If you want to use s3 compatible storage, please set your access_key, secret_key and region to the environment variable AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION,
            set your endpoint to the environment variable RW_S3_ENDPOINT.");
            panic!(
                "Passing s3-compatible is not supported, please modify the environment variable and pass in s3."
            );
        }
        minio if minio.starts_with("minio://") => {
            if config.s3.developer.use_opendal {
                tracing::info!("Using OpenDAL to access minio.");
                ObjectStoreImpl::Opendal(
                    OpendalObjectStore::new_minio_engine(minio, config.clone(), metrics.clone())
                        .unwrap()
                        .monitored(metrics, config),
                )
            } else {
                ObjectStoreImpl::S3(
                    S3ObjectStore::new_minio_engine(minio, metrics.clone(), config.clone())
                        .await
                        .monitored(metrics, config),
                )
            }

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Remove credentials/endpoint from the URL and change the scheme to s3:// in the config
  2. Set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION environment variables for credentials
  3. Set RW_S3_ENDPOINT to the compatible-storage endpoint (e.g. for MinIO/R2/OSS-compatible gateways)
  4. Restart with the updated URL and environment

Example fix

# before
state_store_url = "s3-compatible://bucket/path?access_key=AK&secret=SK&endpoint=http://minio:9000"
# after
state_store_url = "s3://bucket/path"
# plus environment:
# AWS_ACCESS_KEY_ID=AK AWS_SECRET_ACCESS_KEY=SK AWS_REGION=us-east-1 RW_S3_ENDPOINT=http://minio:9000
Defensive patterns

Strategy: validation

Validate before calling

// Validate the state store URL before starting/building the store
let url = config.system.state_store.as_str();
if url.starts_with("s3-compatible://") {
    panic!("s3-compatible:// is removed; use s3:// with RW_S3_ENDPOINT + AWS_* env vars");
}

Type guard

fn is_supported_remote_url(url: &str) -> bool {
    !url.starts_with("s3-compatible://")
        && (url.starts_with("s3://") || url.starts_with("minio://") || url.starts_with("gcs://")
            || url.starts_with("oss://") || url.starts_with("cos://") || url.starts_with("azblob://")
            || url.starts_with("hdfs://") || url.starts_with("disk://") || url.starts_with("memory://")
            || url.is_empty())
}

Prevention

When it happens

Trigger: Passing a store URL starting with s3-compatible:// to build_remote_object_store (directly or via callers like get_object_store, create_sstable_store, restore_hummock_version) — typically from an old config or persisted state directory.

Common situations: Upgrading RisingWave from a version where s3-compatible:// was valid; copying store URLs from old documentation or older config files.

Understand the failure class

Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/6a854f90ca887bd3. Report an issue: GitHub.