Las copias de seguridad a Cloudflare R2 fallan durante la carga multipart con aws-sdk-s3 1.182.0 (método 'downcase' no definido para nil)

Prioridad/Gravedad:

Alta para instancias autoalojadas que utilizan almacenamiento de copias de seguridad compatible con S3, ya que las copias de seguridad programadas fallan después de la creación del archivo.

Plataforma:

Discourse autoalojado en la rama más reciente.

Versión en vivo actual al observar el problema: v2026.4.0-latest

Ruby: 3.4.0

aws-sdk-s3: 1.182.0

Descripción:

Las copias de seguridad hacia Cloudflare R2 fallan en el paso final “Subiendo archivo…”.

La volcado de la base de datos y la creación del archivo local se completan correctamente, pero la subida multipart del archivo de copia de seguridad finalizado falla.

Resultado real:

La copia de seguridad falla con:

EXCEPCIÓN: la subida multipart falló: método 'downcase' no definido para nil

La traza de pila incluye:

aws-sdk-s3-1.182.0/lib/aws-sdk-s3/multipart_file_uploader.rb
lib/backup_restore/s3_backup_store.rb:48
lib/backup_restore/creator.rb:434

Resultado esperado:

El archivo de copia de seguridad debería subirse correctamente al almacén de copias de seguridad compatible con S3 configurado.

Pasos para reproducir:

  1. Configurar el almacenamiento de copias de seguridad en Cloudflare R2 utilizando la ruta de copias de seguridad compatible con S3.
  2. Utilizar un archivo de copia de seguridad mayor que el umbral multipart.
  3. Ejecutar una copia de seguridad manual o programada.
  4. Observar el fallo durante “Subiendo archivo…”.

Configuración relevante:

  • DISCOURSE_BACKUP_LOCATION=s3
  • DISCOURSE_S3_ENDPOINT=https://.r2.cloudflarestorage.com
  • DISCOURSE_S3_FORCE_PATH_STYLE=true
  • DISCOURSE_S3_BACKUP_BUCKET=
  • AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED
  • AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED

Extracto de la traza de pila observada:

algorithm = resp.context.params[:checksum_algorithm]
k = "checksum_#{algorithm.downcase}".to_sym

Esto sugiere que checksum_algorithm es nil en la ruta de subida multipart.

Contexto adicional:

Existe un tema reciente similar en Meta para Backblaze B2:

Además, las entradas del registro de cambios de aws-sdk-s3 posteriores a la versión 1.182.0 parecen relevantes:

  • 1.201.0: Corrección de la subida multipart para respetar el modo request_checksum_calculation cuando_required
  • 1.210.2: Retrocede a los checksums de solicitud en encabezados al usar endpoints personalizados o proveedores de endpoints para las operaciones PutObject y UploadPart

Actualmente, Discourse main parece seguir bloqueando aws-sdk-s3 en la versión 1.182.0:

https://raw.githubusercontent.com/discourse/discourse/main/Gemfile.lock

No he revisado esto en un tiempo, pero así es como lo he manejado en el pasado:

No lo consideran un bug porque no pretenden dar soporte a cada servicio del planeta que no sea totalmente compatible con S3.

No recuerdo exactamente para qué sitios estaba haciendo esto, pero tampoco recuerdo haber cambiado nada al respecto recientemente, así que creo que este sigue siendo el “mejor” workaround.

Creo que hubo otros temas sobre esto cuando AWS lanzó la nueva biblioteca que rompió las ofertas de todos los demás.

2 Me gusta

Gracias, esto lo solucionó para mí.

Aplicé el método alternativo directamente en app.yml mediante after_bundle_exec, fijé aws-sdk-s3 en 1.177.0 y aws-sdk-core en 3.215, y luego reconstruí el contenedor. Después de eso, las copias de seguridad manuales a Cloudflare R2 volvieron a tener éxito, y las cargas desde el navegador que antes fallaban también comenzaron a funcionar.

En mi caso, los errores aparecían como multipart upload failed: undefined method 'downcase' for nil en aws-sdk-s3 1.182.0.

Agradezco el método alternativo.

1 me gusta

Corrección… este método de trabajo también funcionó para mí. Solo tuve que ponerlo en su propio bloque hooks: y no agregarlo a un bloque hooks: existente. Qué tonto de mi parte.