Problem/Motivation
FlysystemFileSystem::prepareDirectory() always asks the adapter for Visibility::PUBLIC:
$fs->createDirectory($target, [Config::OPTION_DIRECTORY_VISIBILITY => Visibility::PUBLIC]); // ... $fs->setVisibility($target, Visibility::PUBLIC);
With the AWS S3 adapter this translates into an object ACL (public-read). Since April 2023 new S3 buckets default to Object Ownership = Bucket owner enforced, which disables ACLs entirely; any request carrying an ACL is rejected:
AccessControlListNotSupported: The bucket does not allow ACLsBuckets with Block Public Access enabled reject the same request with AccessDenied / BlockPublicAcls.
The consequence is that every directory preparation fails on such a bucket — which is the recommended setup when the bucket is served through CloudFront with an Origin Access Control — so file uploads, image style derivative directories and anything else going through prepareDirectory() return FALSE.
Note that per-object ACLs are not what makes those files readable in that architecture: public access is granted by the bucket policy / CloudFront distribution. Requesting public-read buys nothing and breaks the common case.
FlysystemFileSystem::chmod() already tolerates adapters that cannot set visibility (MinIO's HTTP 501 / NotImplemented), but the exception message for an ACL-disabled AWS bucket is different, so it is logged as a warning on every write.
Steps to reproduce
- Create an S3 bucket with Object Ownership = Bucket owner enforced (the default) and/or Block Public Access enabled.
- Configure a Flysystem scheme with the
aws_s3driver pointing at it, public visibility. - Upload a file, or flush image styles and request a derivative.
prepareDirectory()fails; watchdog shows the ACL error and the file is not written.
Proposed resolution
Never request PUBLIC visibility for directories — request PRIVATE, which every S3-compatible backend accepts regardless of the Object Ownership setting. Public readability of the scheme is a bucket-policy/CDN concern, not a per-object ACL concern, and S3 has no real directories anyway (the "directory" is a zero-byte key or nothing at all).
Also extend the "unsupported visibility" detection in chmod() with BlockPublicAcls so those buckets stop producing warning noise.
Alternative worth discussing: make the requested directory visibility configurable per scheme, defaulting to PRIVATE. That is more flexible but adds config surface for a value that has no observable effect on S3-backed public schemes.
Remaining tasks
- Review, decide between the hardcoded PRIVATE and a per-scheme setting.
- Test coverage for
prepareDirectory()asserting the visibility passed to the adapter.
User interface changes
None.
API changes
None.
Data model changes
None.
Disclosure IA
AI assistance disclosure: AI (Claude, Cursor) was used to help diagnose this issue and draft the patch/fix.
| Comment | File | Size | Author |
|---|---|---|---|
| flysystem-01-directory-visibility-acls-disabled.patch | 2.99 KB | luigisa |
Issue fork flysystem-3616482
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
luigisa commentedComment #5
lisa.rae commentedI pushed one change, adding a fallback to check the adapter’s visibility setting before a final fallback to PRIVATE. Also added a test that covers checking the adapter’s visibility setting.
Please review and test, if acceptable please mark RTBC.
Comment #6
luigisa commentedIt works as expected. Thank you
Comment #9
lisa.rae commentedComment #11
lisa.rae commented