Impossible de téléverser des Avatars avec S3 Storage activé (Fichier présent, échec)

Salut à tous,

Je rencontre un problème étrange avec Discourse + stockage S3.

Lors du téléchargement d’avatars, je reçois une erreur comme celle ci-dessous, même si le fichier existe dans le bucket S3 et est accessible via une s3_cdn_url valide.

Les téléchargements pour les messages et les pièces jointes fonctionnent parfaitement. La seule chose qui échoue, ce sont les téléchargements d’avatars utilisateur.


:fire: Message d’erreur de gig.ovh/logs


Message (2 copies signalées)

Impossible de trouver le fichier dans le magasin situé à l'URL : //gig.s3.ru-1.storage.selcloud.ru/original/1X/fd42dfa3362b66090450f2ae40f0917193fcd355.jpeg

Backtrace

/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active\ _support/broadcast\ _logger.rb:134:in `block in error'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in `block in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active\ _support/broadcast\ _logger.rb:231:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active\ _support/broadcast\ _logger.rb:134:in `error'
/var/www/discourse/app/models/optimized_image.rb:91:in `block in create\ _for'
/var/www/discourse/app/models/optimized\ _image.rb:19:in `block (2 levels) in lock'
/var/www/discourse/lib/distributed_mutex.rb:53:in `block in synchronize'
/var/www/discourse/lib/distributed\ _mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed\ _mutex.rb:34:in `synchronize'
/var/www/discourse/app/models/optimized_image.rb:19:in `block in lock'
/var/www/discourse/lib/distributed\ _mutex.rb:53:in `block in synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed\ _mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:34:in `synchronize'
/var/www/discourse/app/models/optimized\ _image.rb:18:in `lock'
/var/www/discourse/app/models/optimized_image.rb:83:in `create\ _for'
/var/www/discourse/app/models/upload.rb:151:in `get_optimized_image'
/var/www/discourse/app/controllers/user_avatars_controller.rb:219:in `get\ _optimized_image'
/var/www/discourse/app/controllers/user\ _avatars_controller.rb:137:in `show_in_site'
/var/www/discourse/app/controllers/user_avatars_controller.rb:90:in `block (2 levels) in show'
/var/www/discourse/lib/hijack.rb:68:in `instance_eval'
/var/www/discourse/lib/hijack.rb:68:in `block (2 levels) in hijack'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/i18n-1.14.7/lib/i18n.rb:353:in `with_locale'
/var/www/discourse/lib/hijack.rb:68:in `block in hijack'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:911:in `callback_on_resolution'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:797:in `call\ _callback'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:803:in `call_callbacks'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:692:in `resolve\ _with'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:1325:in `resolve'
/var/www/discourse/lib/scheduler/defer.rb:125:in `block in do\ _work'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails\ _multisite-6.1.0/lib/rails\ _multisite/connection\ _management/null\ _instance.rb:49:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in `with\ _connection'
/var/www/discourse/lib/scheduler/defer.rb:119:in `do_work'
/var/www/discourse/lib/scheduler/defer.rb:105:in `block (2 levels) in start\ _thread'

Ceci est une URL S3 pour le conteneur

//gig.s3.ru-1.storage.selcloud.ru/original/1X/fd42dfa3362b66090450f2ae40f0917193fcd355.jpeg

L’image est disponible à l’URL :

https://s3.gig.ovh/original/1X/fd42dfa3362b66090450f2ae40f0917193fcd355.jpeg

:white_check_mark: Informations supplémentaires

  • Version de Discourse : (dernière version stable)
  • Stockage externe compatible S3 utilisé (enable_s3_uploads = true)
  • s3_cdn_url est correctement configuré et utilisé
  • L’URL CDN renvoie le fichier avec succès
  • Le fichier est confirmé présent à l’emplacement S3 attendu
  • Les autres téléchargements (images, pièces jointes, etc.) fonctionnent correctement
  • L’erreur ne se produit qu’avec les avatars utilisateur

:red_question_mark:Question

Quelle pourrait être la cause de l’échec de Discourse à récupérer le fichier pour le traitement de l’avatar, alors que le fichier exact existe et est accessible via la bonne URL CDN ?

Y a-t-il quelque chose de spécifique au traitement des avatars (comme get_optimized_image) qui pourrait être mal configuré ou mis en cache de manière incorrecte ?

Toutes suggestions ou éclaircissements seraient appréciés !

Merci :folded_hands:

1 « J'aime »

Salut — as-tu finalement résolu ce problème ?

Je rencontre exactement le même symptôme sur Discourse + S3 (avatars uniquement) :
Impossible de trouver le fichier dans le magasin situé à l'URL : //\u003cbucket\u003e.s3.dualstack.\u003cregion\u003e.amazonaws.com/original/1X/\u003chash\u003e.jpeg

Quelques détails sur ma configuration, au cas où elle correspondrait à la tienne :

  • enable_s3_uploads = true, les objets se trouvent dans original/* et optimized/* (pas de préfixe uploads/default)

  • Accès via CloudFront (OAC), le bucket lui-même est privé

  • L’objet existe à cette clé ; l’URL CDN fonctionne

  • L’erreur se produit uniquement pour le traitement des avatars

  • (Possible complication) les téléchargements sont chiffrés avec SSE-KMS

Si tu as trouvé la cause racine ou une solution (changement de politique, permissions KMS, alignement des chemins de bucket, etc.), pourrais-tu partager ce qui a fonctionné ? Merci !