diff --git a/lib/src/minio.dart b/lib/src/minio.dart
index b203ff359985ddce671eebd4c233130619feab81..a1d1f6e21f0b1c59b08a6f2a7eeffa2da16c8077 100644
--- a/lib/src/minio.dart
+++ b/lib/src/minio.dart
@@ -75,10 +75,13 @@ class Minio {
     MinioInvalidBucketNameError.check(bucket);
     try {
       final response = await _client.request(method: 'HEAD', bucket: bucket);
+      validate(response);
       return (response.statusCode == 200 || response.statusCode == 403);
     } on MinioS3Error catch (e) {
       final code = e.error.code;
-      if (code == 'NoSuchBucket' || code == 'NotFound') return false;
+      if (code == 'NoSuchBucket' || code == 'NotFound' || code == 'Not Found') {
+        return false;
+      }
       rethrow;
     } on StateError catch (e) {
       // Insight from testing: in most cases, AWS S3 returns the HTTP status code
@@ -87,11 +90,11 @@ class Minio {
       // status code 404 as officially documented. Then, this redirect response
       // lacks the HTTP header `location` which causes this exception in Dart's
       // HTTP library (`http_impl.dart`).
-      if (e.message == 'Response has no Location header for redirect')
+      if (e.message == 'Response has no Location header for redirect') {
         return false;
+      }
       rethrow;
     }
-    return true;
   }
 
   int _calculatePartSize(int size) {
@@ -456,6 +459,7 @@ class Minio {
       method: 'GET',
       region: region ?? 'us-east-1',
     );
+    validate(resp);
     final bucketsNode =
         xml.XmlDocument.parse(resp.body).findAllElements('Buckets').first;
     return bucketsNode.children.map((n) => Bucket.fromXml(n)).toList();
diff --git a/lib/src/minio_helpers.dart b/lib/src/minio_helpers.dart
index b8d2e381b4993c16fd4936aef317a1b9fd49aa47..4cd2fdc13e97ece4aabecf0e65aacda27eae296d 100644
--- a/lib/src/minio_helpers.dart
+++ b/lib/src/minio_helpers.dart
@@ -217,9 +217,17 @@ Future<void> validateStreamed(
 
 void validate(Response response, {int expect}) {
   if (response.statusCode >= 400) {
-    final body = xml.XmlDocument.parse(response.body);
-    final error = Error.fromXml(body.rootElement);
-    throw MinioS3Error(error.message, error, response);
+    var error;
+
+    // Parse HTTP response body as XML only when not empty
+    if (response.body == null || response.body.isEmpty) {
+      error = Error(response.reasonPhrase, null, response.reasonPhrase, null);
+    } else {
+      final body = xml.XmlDocument.parse(response.body);
+      error = Error.fromXml(body.rootElement);
+    }
+
+    throw MinioS3Error(error?.message, error, response);
   }
 
   if (expect != null && response.statusCode != expect) {
diff --git a/test/minio_dart_test.dart b/test/minio_dart_test.dart
index cc066cf05713e9b39ede297e02d059a569471ea3..e8626bcee58a4aaa0effa6be67cd70482564e658 100644
--- a/test/minio_dart_test.dart
+++ b/test/minio_dart_test.dart
@@ -39,6 +39,58 @@ void main() {
       );
     });
   });
+
+  group('bucketExists', () {
+    final bucketName = DateTime.now().millisecondsSinceEpoch.toString();
+
+    setUpAll(() async {
+      final minio = _getClient();
+      await minio.makeBucket(bucketName);
+    });
+
+    tearDownAll(() async {
+      final minio = _getClient();
+      await minio.removeBucket(bucketName);
+    });
+
+    test('bucketExists() returns true for an existing bucket', () async {
+      final minio = _getClient();
+      expect(await minio.bucketExists(bucketName), equals(true));
+    });
+
+    test('bucketExists() returns false for a non-existent bucket', () async {
+      final minio = _getClient();
+      expect(await minio.bucketExists('non-existing-bucket-name'), equals(false));
+    });
+
+    test('bucketExists() fails due to wrong access key', () async {
+      final minio = _getClient(accessKey: 'incorrect-access-key');
+      expect(
+        () async => await minio.bucketExists(bucketName),
+        throwsA(
+          isA<MinioError>().having(
+            (e) => e.message,
+            'message',
+            'Forbidden',
+          ),
+        ),
+      );
+    });
+
+    test('bucketExists() fails due to wrong secret key', () async {
+      final minio = _getClient(secretKey: 'incorrect-secret-key');
+      expect(
+        () async => await minio.bucketExists(bucketName),
+        throwsA(
+          isA<MinioError>().having(
+            (e) => e.message,
+            'message',
+            'Forbidden',
+          ),
+        ),
+      );
+    });
+  });
 }
 
 /// Initializes an instance of [Minio] with per default valid configuration.