diff -u b/src/Flysystem/S3.php b/src/Flysystem/S3.php
--- b/src/Flysystem/S3.php
+++ b/src/Flysystem/S3.php
@@ -219,30 +219,32 @@
       $this->generateImageStyle($target);
     }
 
-    // This method can only return FALSE if the wrapper does not exist, and not
-    // if there is an error in generating the URL. If an asset is missing on S3,
-    // then the getVisibility() call will throw an exception. In that case,
-    // we log it and return an unsigned URL so we don't break the expected
-    // return or completely break the response.
-    try {
-      if ($this->options['ACL'] != 'public-read' && $this->getAdapter()->getVisibility($target)['visibility'] == AdapterInterface::VISIBILITY_PRIVATE) {
-        // Use getCommand() so we don't actually make a request yet.
-        $command = $this->client->getCommand('getObject', [
-          'Bucket' => $this->bucket,
-          'Key' => $target,
-        ]);
-        $request = $this->client->createPresignedRequest($command, $this->expires);
+    if (isset($this->options['ACL']) && $this->options['ACL'] != 'public-read') {
+      // This method can only return FALSE if the wrapper does not exist, and not
+      // if there is an error in generating the URL. If an asset is missing on S3,
+      // then the getVisibility() call will throw an exception. In that case,
+      // we log it and return an unsigned URL so we don't break the expected
+      // return or completely break the response.
+      try {
+        if ($this->getAdapter()->getVisibility($target)['visibility'] == AdapterInterface::VISIBILITY_PRIVATE) {
+          // Use getCommand() so we don't actually make a request yet.
+          $command = $this->client->getCommand('getObject', [
+            'Bucket' => $this->bucket,
+            'Key' => $target,
+          ]);
+          $request = $this->client->createPresignedRequest($command, $this->expires);
 
-        return (string) $request->getUri();
+          return (string) $request->getUri();
+        }
       }
-    }
-    catch (S3Exception $e) {
-      // Inline watchdog_exception() so we can use it with our injected service.
-      // Use a default value if $message is not set.
-      $message = '%type: @message in %function (line %line of %file).';
-      $variables = Error::decodeException($e);
+      catch (S3Exception $e) {
+        // Inline watchdog_exception() so we can use it with our injected service.
+        // Use a default value if $message is not set.
+        $message = '%type: @message in %function (line %line of %file).';
+        $variables = Error::decodeException($e);
 
-      $this->logger->error($message, $variables);
+        $this->logger->error($message, $variables);
+      }
     }
 
     return $this->urlPrefix . '/' . UrlHelper::encodePath($target);
diff -u b/tests/src/Unit/Flysystem/S3Test.php b/tests/src/Unit/Flysystem/S3Test.php
--- b/tests/src/Unit/Flysystem/S3Test.php
+++ b/tests/src/Unit/Flysystem/S3Test.php
@@ -225,6 +225,9 @@
       'bucket'   => 'my-bucket',
       'expires' => $expires_timestamp,
       'public'   => TRUE,
+      'options' => [
+        'ACL' => 'private'
+      ],
     ];
 
     $client = $this->prophesize(S3Client::class);
@@ -250,6 +253,9 @@
       'bucket'   => 'my-bucket',
       'expires' => strtotime('10 seconds'),
       'public'   => TRUE,
+      'options' => [
+        'ACL' => 'private'
+      ],
     ];
 
     $client = $this->prophesize(S3Client::class);
