Search code examples
laravelamazon-s3backblaze

How do I resolve a 'Unsupported value for canned acl 'private' error' on Backblaze B2 S3 Compatible API?


After getting help with the issue in this question, I'm getting another error despite successfully uploading the image which I can see on my Backblaze dashboard and within my app.

Unable to write file at location: profile-photos/0Oafj0VpwBbrMtvgLEnBmGl3UsL4rrUaD7HLzRDA.jpg. 
Error executing "PutObject" on "https://xxx.s3.us-west-004.backblazeb2.com/profile-photos/0Oafj0VpwBbrMtvgLEnBmGl3UsL4rrUaD7HLzRDA.jpg"; AWS HTTP error: Client error: `PUT https://xxx.s3.us-west-004.backblazeb2.com/profile-photos/0Oafj0VpwBbrMtvgLEnBmGl3UsL4rrUaD7HLzRDA.jpg` resulted in a `400 Bad Request` response: 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
  <Error> 
    <Code>InvalidArgument</Code> 
    <Message>Unsupporte (truncated...) 
InvalidArgument (client): Unsupported value for canned acl 'private' - 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Error> 
  <Code>InvalidArgument</Code> 
  <Message>Unsupported value for canned acl 'private'</Message> 
</Error>

What can I do to resolve this?


Solution

  • This is one of the differences between Backblaze B2's S3-compatible API and Amazon S3. Backblaze B2 controls visibility at the bucket, rather than the object, level, and you have two choices: private or public-read (shown as just 'public' in the Backblaze web UI). If you specify an ACL when you put an object in a bucket, it must match the ACL of the bucket. Here is the relevant section of the docs.

    It looks like Laravel is trying to create a private object in a public-read bucket, so B2 is returning the Unsupported value error.

    There are two ways to fix this. Either:

    • Change the visibility of your bucket from public-read to private (Bucket Settings in the web UI), or
    • Configure Laravel to create objects with the public-read canned ACL.

    From this discussion at Laracasts, it looks like you can set the default visibility in the s3 config in config/filesystems.php. If you set public here, it is mapped to public-read by the S3 driver.

    's3' => [
                'driver' => 's3',
                'key' => 'your-key',
                'secret' => 'your-secret',
                'region' => 'your-region',
                'bucket' => 'your-bucket',
                'visibility' => 'public',
            ],