S3 Errors Uploading Profile Photos

I am running the latest beta and have enabled S3 to manage uploaded files.

Uploads in posts work fine (file is uploaded to s3 and displayed in the post), but I now find that trying to upload profile photos creates “Access Denied” errors in the UI. There is nothing in the admin error log.

Some of my early users do seem to have managed to upload avatar images, but these are stored locally, e.g. looking at the source:

<img alt="" width="45" height="45" src="/user_avatar/example.com/jackie/90/29_2.png" class="avatar" title="image title" aria-label="Imagery/FIT">

Is there a way to migrate profile images to S3, and ensure new images can be uploaded there?

EDIT: should have mentioned, I do have secure media uploads enabled.

2 Likes

Do you happen to be using Cloudflare? I believe that the profile images are indeed stored on S3, but are proxied via your server. I resolved a similar issue to this (all uploaded avatars appearing blank), I had to whitelist the server IP address in Cloudflare to fix it.

2 Likes

Thanks - but no, not using a CDN — am just using plain S3 but with secure media. Am not sure how to check if requests are being proxied, but see curl header output below:

That suggests to me it’s not proxied, but I don’t know enough to be sure…

curl -I https://example.com/user_avatar/discourse.psy.plymouth.ac.uk/jackie/90/29_2.png
HTTP/2 200 
server: nginx
date: Thu, 09 Sep 2021 11:26:33 GMT
content-type: image/jpeg
content-length: 4068
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-download-options: noopen
x-permitted-cross-domain-policies: none
referrer-policy: strict-origin-when-cross-origin
x-discourse-route: user_avatars/show
last-modified: Thu, 09 Sep 2021 09:38:05 GMT
content-transfer-encoding: binary
cache-control: max-age=31556952, public, immutable

1 Like

That URL structure is consistent with a proxied avatar, which is confusing (the implementation of the avatar urls here on meta is different to standard Discourse instances). I don’t really know from the curl output if there is some info there that rules out Discourse proxying the avatars (I’m not an expert).

From my past experience with this, if the post images are being uploaded to S3, then the avatars also are, unless doing something quite custom. I haven’t tried secure media uploads before or using S3 without a CDN, so those could perhaps make a significant difference.

Would be good to try upload a new avatar and confirm if you can find the file in your local storage or in the S3 bucket.

My guess would be something along the lines of the server IP needing to be whitelisted with S3. Not an expert though, hopefully someone else can chime in.

1 Like

The problem is that s3 uploads work for posts, but don’t for avatar image uploads. My hunch is that the only users that do have avatars are ones that uploaded images before s3 was set up, but I can’t confirm that.

1 Like

This might be helpful: How are avatars stored and accessed? - #5 by DanielMarquard

I had a similar issue, post images worked, profile images did not display. The uploads were successfully uploading to S3 for both, but there was an issue displaying them (server IP rate limited/blocked).

2 Likes

Can confirm that when I try to upload an avatar the progress bar updates, and gets to 100%, but only then says “Error: Access Denied”.

Looking in the js console, I get the error:

https://discourse.psy.plymouth.ac.uk/uploads.json?client_id=0a2569993a6b43d6b5f8c60fdd2c913e
Failed to load resource: the server responded with a status of 422 ()

And if I follow that url:

{"errors":["The requested URL or resource could not be found."],"error_type":"not_found"}

Checking the S3 bucket, nothing has made it to the ‘Originals’ folder.

This is in contrast to the situation when I upload and image to a post: then everything works fine and the image does appear in the s3 bucket, and is thumbnailed/optimized too.

1 Like

HTTP status 422 is apparently unprocessable entity. This suggests to me that Discourse doesn’t like the upload for some reason but it could be something else - I think 422 basically just means “the request was formed correctly but something in the request is wrong”.

Is the image you’re trying to upload an unusual image type or perhaps a gigantic image?
Have you tried including that exact image file in a post?

The avatar (by default) gets resized to a bunch of different sizes so that could be where it’s failing for some reason, e.g. hitting a memory limit if the image is gigantic. That’s mostly speculation though.

I don’t think I would expect to see 422 from S3 and it’s not listed in the error responses on their API reference, so I think the problem is happening in Discourse before it gets as far as trying to upload to S3.

1 Like

It’s definitely something to do with avatar image handling. Have just tried again with the same image (using the iOS mobile client this time) and it uploads fine inside a post but gives same access denied error when using same image as avatar.

Can anyone else using s3 with secure media replicate the error? Could it be something to do with bucket permissions given the uploading for a post does work?

1 Like