Error al subir avatares con S3 Storage habilitado (Archivo existe, pero falla)

Hola a todos,

Estoy experimentando un problema extraño con Discourse + almacenamiento S3.

Al subir avatares, recibo un error como el siguiente, a pesar de que el archivo existe en el bucket S3 y es accesible a través de una s3_cdn_url válida.

Las cargas de publicaciones y archivos adjuntos funcionan perfectamente. Lo único que falla son las cargas de avatares de usuario.


:fire: Mensaje de error de gig.ovh/logs


Mensaje (se informaron 2 copias)

No se pudo encontrar el archivo en la tienda ubicada en la 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 `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'

Esa es una URL S3 para el contenedor

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

La imagen está disponible en la URL:

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

:white_check_mark: Información adicional

  • Versión de Discourse: (última estable)
  • Almacenamiento externo compatible con S3 utilizado (enable_s3_uploads = true)
  • s3_cdn_url está correctamente configurado y en uso
  • La URL de CDN devuelve el archivo con éxito
  • Se confirma la presencia del archivo en la ubicación S3 esperada
  • Otras cargas (imágenes, archivos adjuntos, etc.) funcionan bien
  • El error solo ocurre con avatares de usuario

:red_question_mark:Pregunta

¿Qué podría causar que Discourse no pueda recuperar el archivo para el procesamiento de avatares, mientras que el archivo exacto existe y es accesible a través de la URL de CDN correcta?

¿Hay algo específico en el procesamiento de avatares (como get_optimized_image) que podría estar mal configurado o en caché incorrectamente?

¡Agradecería cualquier sugerencia o información!

¡Gracias! :folded_hands:

1 me gusta

Hola, ¿resolviste esto alguna vez?

Estoy experimentando exactamente el mismo síntoma en Discourse + S3 (solo avatares):
Could not find file in the store located at url: //<bucket>.s3.dualstack.<region>.amazonaws.com/original/1X/<hash>.jpeg

Algunos detalles sobre mi configuración, en caso de que coincida con la tuya:

  • enable_s3_uploads = true, los objetos viven en original/* y optimized/* (sin prefijo uploads/default)

  • Acceso a través de CloudFront (OAC), el bucket en sí es privado

  • El objeto existe en esa clave; la URL de la CDN funciona

  • El error ocurre solo para el procesamiento de avatares

  • (Posible complicación) las subidas están cifradas con SSE-KMS

Si encontraste la causa raíz o una solución (cambio de política, permisos KMS, alineación de la ruta del bucket, etc.), ¿podrías compartir qué funcionó? ¡Gracias!