S3: uploads fail with AccessControlListNotSupported on buckets with BucketOwnerEnforced

Open Beginner friendly
#5,366 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
aws, javascript
Domain
backend, cloud

Research direction

Start in lib/storage/s3.js and inspect the copyIn, enable, and disable entry points, including how bucketObjectsACL and disabledBucketObjectsACL are initialized. Done means false prevents ACL parameters and PutObjectAclCommand calls while the existing default ACL behavior remains unchanged.

Written by the indexing model from the issue text.

Description

bug

Problem

Since April 2023, AWS S3 creates all new buckets with ObjectOwnership: BucketOwnerEnforced
by default, which disables ACLs entirely. uploadfs always sends ACL: 'public-read'
(or whatever bucketObjectsACL is set to) in every copyIn, enable, and disable call,
causing all uploads to fail with:

AccessControlListNotSupported: The bucket does not allow ACLs

Root Cause

In lib/storage/s3.js, the ACL param is always included in requests:

// copyIn
const params = {
  Bucket: bucket,
  ACL: bucketObjectsACL, // always sent, no way to disable
  ...
};

// enable / disable also always call PutObjectAclCommand

Expected Behavior

It should be possible to pass bucketObjectsACL: false (and disabledBucketObjectsACL: false)
to skip sending ACL headers entirely, for use with modern S3 buckets or S3-compatible
storage that does not support ACLs.

Suggested Fix

bucketObjectsACL = options.bucketObjectsACL === false
  ? false
  : (options.bucketObjectsACL || 'public-read');

disabledBucketObjectsACL = options.disabledBucketObjectsACL === false
  ? false
  : (options.disabledBucketObjectsACL || 'private');

Then in copyIn, enable, and disable — skip ACL if value is false.

This is fully backward compatible — existing users who don't set these options
get the same public-read default as before.

Related

Dominant language
JavaScript
Stars
4.6k
Forks
652
Avg merge
17h 36m
Merged PRs (30d)
29

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apostrophecms/apostrophe

All issues in apostrophecms/apostrophe

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.