Repository navigation
fix(s3): return NoSuchBucket when listing missing bucket - #295
Conversation
| } | ||
| let engine = state.engine().clone(); | ||
| let bucket_to_check = bucket.clone(); | ||
| SendWrapper::new(async move { engine.stat_bucket(&bucket_to_check).await }).await?; |
There was a problem hiding this comment.
🔵 Low · Handler-level stat adds a second cluster-wide fan-out per list page and leaves the engine bug in place
The missing-bucket bug comes from Engine::list_one_set. It drops every walk_dir error, VolumeNotFound included, and returns Ok(Vec::new()) when quorum fails. So Engine::list says a missing bucket is an empty one. This PR works around that in the handler: every ListObjects page now runs stat_bucket, which calls stat_vol on all backends in the cluster, and then runs the walk.
Two costs follow:
- Every paginated listing makes one extra round trip to every disk.
- Any other
Engine::listcaller still gets an empty result for a missing bucket.
A smaller fix is to make list_one_set count VolumeNotFound results and return StorageError::BucketNotFound when they reach quorum, the same logic stat_bucket already uses. The only case that still needs an explicit stat_bucket is the max_keys == 0 short-circuit in list_page, and it can do that check before returning the empty page.
Fixes #293. Checks bucket existence before ListObjects V1 and V2, including max-keys=0. Adds regression tests for missing and existing buckets.