philkunz commented on issue #851:
URL: 
https://github.com/apache/arrow-rs-object-store/issues/851#issuecomment-6644934211

   Confirmed with Rust `object_store 0.14.2` against an S3-compatible server: 
using an incorrect signing secret gives HTTP 403 `SignatureDoesNotMatch`. 
`head` returns `Error::PermissionDenied`, while `list_with_delimiter` returns 
`Error::Generic`. Both operations succeed with the correct secret.
   
   A small reproducer, with a known existing bucket and object (`probe.bin`):
   
   ```toml
   [package]
   name = "s3-list-error-repro"
   version = "0.1.0"
   edition = "2024"
   
   [dependencies]
   object_store = { version = "=0.14.2", default-features = false, features = 
["aws"] }
   tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
   ```
   
   ```rust
   use std::env;
   use object_store::{aws::AmazonS3Builder, path::Path, ObjectStore, 
ObjectStoreExt};
   
   fn category<T>(result: object_store::Result<T>) -> &'static str {
       match result {
           Ok(_) => "Ok",
           Err(object_store::Error::PermissionDenied { .. }) => 
"PermissionDenied",
           Err(object_store::Error::Unauthenticated { .. }) => 
"Unauthenticated",
           Err(object_store::Error::NotFound { .. }) => "NotFound",
           Err(object_store::Error::Generic { .. }) => "Generic",
           Err(_) => "another category",
       }
   }
   
   #[tokio::main]
   async fn main() -> Result<(), Box<dyn std::error::Error>> {
       let secret = env::var("AWS_SECRET_ACCESS_KEY")?;
       for (label, secret) in [("correct", secret.clone()), ("wrong", 
format!("{secret}x"))] {
           let store = AmazonS3Builder::new()
               .with_endpoint(env::var("S3_ENDPOINT")?)
               .with_region(env::var("AWS_REGION")?)
               .with_bucket_name(env::var("S3_BUCKET")?)
               .with_access_key_id(env::var("AWS_ACCESS_KEY_ID")?)
               .with_secret_access_key(secret)
               .with_allow_http(true) // for a local HTTP fixture
               .build()?;
           println!("{label}: HEAD={} LIST={}",
               category(store.head(&Path::from("probe.bin")).await),
               category(store.list_with_delimiter(None).await));
       }
       Ok(())
   }
   ```
   
   Expected after preserving categories: `wrong: HEAD=PermissionDenied 
LIST=PermissionDenied`. Observed: `wrong: HEAD=PermissionDenied LIST=Generic`.
   
   In 
[`src/aws/client.rs:129–138`](https://github.com/apache/arrow-rs-object-store/blob/c216edef0ac3d0d39da5bcdfeed3dcd034e26597/src/aws/client.rs#L129),
 `Error::ListRequest` still falls into the generic arm instead of 
`RetryError::error`. The private wrapper types prevent a caller from inspecting 
the HTTP status through the public typed error. This also affects identifying 
missing buckets and connection failures; this reproduction specifically 
exercises 403.
   
   Rechecked on 2026-11-04: #857 was **closed without merging**, and current 
`main` (`c216edef0ac3d0d39da5bcdfeed3dcd034e26597`) retains the conversion 
above. Is a revised fix routing `ListRequest` through the existing mapper still 
welcome?
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to