@ -377,9 +377,18 @@ func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Reque
}
}
}
}
err := s3a . WithFilerClient ( false , func ( client filer_pb . SeaweedFilerClient ) error {
// Delete bucket directory first, then collection. This order ensures that if
// collection deletion fails, the bucket directory is already gone, preventing
// the "collection exists but bucket directory missing" inconsistency that blocks
// bucket recreation. An orphaned collection is harmless and will be cleaned up
// or reused when the bucket is recreated.
err := s3a . rm ( s3a . option . BucketsPath , bucket , false , true )
if err != nil {
s3err . WriteErrorResponse ( w , r , s3err . ErrInternalError )
return
}
// delete collection
err = s3a . WithFilerClient ( false , func ( client filer_pb . SeaweedFilerClient ) error {
deleteCollectionRequest := & filer_pb . DeleteCollectionRequest {
deleteCollectionRequest := & filer_pb . DeleteCollectionRequest {
Collection : s3a . getCollectionName ( bucket ) ,
Collection : s3a . getCollectionName ( bucket ) ,
}
}
@ -393,15 +402,9 @@ func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Reque
} )
} )
if err != nil {
if err != nil {
s3err . WriteErrorResponse ( w , r , s3err . ErrInternalError )
return
}
err = s3a . rm ( s3a . option . BucketsPath , bucket , false , true )
if err != nil {
s3err . WriteErrorResponse ( w , r , s3err . ErrInternalError )
return
// Log but don't fail — the bucket directory is already removed, so the bucket
// is effectively deleted. The orphaned collection will be cleaned up or reused.
glog . Errorf ( "DeleteBucketHandler: failed to delete collection for bucket %s: %v" , bucket , err )
}
}
// Clean up bucket-related caches, locks, and metrics after successful deletion
// Clean up bucket-related caches, locks, and metrics after successful deletion