flysystem-aws-s3-v3
flysystem-aws-s3-v3 copied to clipboard
Error creating directory when public access is blocked to the bucket.
I am using Laravel 9 and I am trying to create a directory in a bucket.
Storage::disk('s3')->makeDirectory("tenants/abcde");
The tenants
directory already exists, but running the above command throws the following error.
League\Flysystem\UnableToWriteFile with message 'Unable to write file at location: tenants/abcde/.'
I have checked the credentials that I am using and the access_key
has S3FullAccess
. The strange thing is, I created a folder directly using the S3 console and I am able to programmatically add files in the folder or even delete the folder, but if I try to make a new directory, I get the above error. I have even tried to use the root access_key
and I still get the same error.
On further debugging, I see the following error from AWS.
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessControlListNotSupported</Code><Message>The bucket does not all (truncated...)
AccessControlListNotSupported (client): The bucket does not allow ACLs - <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessControlListNotSupported</Code><Message>The bucket does not allow ACLs</Message>
My bucket is public access blocked as recommended by Amazon's best practice and the only way to read files are through cloudfront. There is a bucket policy that allows read access only through cloudfront.
Having said that, debugging the underlying code the following code doesn't work and results in the error above.
use Aws\S3\S3Client;
$client = new S3Client([
'credentials' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY')
],
'region' => 'us-east-1',
'version' => 'latest',
]);
$client->putObject(array(
'Bucket' => 'bucket-name',
'Key' => "tenant/cdfe",
'Body' => "",
'ACL' => 'public-read'
));
but removing the ACL
from the array passed to putObject
works correctly.
@abishekrsrikaanth what if you use an ACL of private
?
@frankdejonge ACL set to private
works.
@abishekrsrikaanth then you can configure the adapter to have a default directory visibility of private to resolve this issue. The visibility constructor property allows you to use a PortableVisibilityConverter instance which accepts this configuration setting.