Skip to content

🐛(s3/backend) Doc content is not saved to s3 | XAmzContentSHA256Mismatch #1202

@jco-c

Description

@jco-c

Bug Report

Problematic behavior
Document content is not saved. When creating a document and adding content and then switching document, the document still exists but the content is gone.

The logs show repeatedly a XAmzContentSHA256Mismatch error when the backend tries to use _saveobj.upload_fileobj(content, ExtraArgs=params, Config=self.transfer_config) and subsequent calls (not familiar with the backend code). Error message is shown below.

Expected behavior/code
That the document content is saved.

Steps to Reproduce

  1. Open a new document
  2. Add content
  3. Switch to another doc and back
  4. Content is gone.

Environment

  • Docs version: 3.4.2
  • Instance url: docs.lielacloud.org
  • s3 backend: Ionos (german hoster for object storage & more)

Possible Solution

Additional context/Screenshots
Error message:

Error Message in Logs

backend-1 | 2025-07-20 10:29:13,441 request.summary ERROR An error occurred (XAmzContentSHA256Mismatch) when calling the PutObject operation: None
backend-1 | 2025-07-20 10:29:13,442 django.request ERROR Internal Server Error: /api/v1.0/documents/3fa9ad28-c31c-4d34-98af-d353628a7b28/
backend-1 | Traceback (most recent call last):
backend-1 | File "/usr/local/lib/python3.13/site-packages/django/core/handlers/exception.py", line 55, in inner
backend-1 | response = get_response(request)
backend-1 | File "/usr/local/lib/python3.13/site-packages/django/core/handlers/base.py", line 197, in _get_response
backend-1 | response = wrapped_callback(request, *callback_args, **callback_kwargs)
backend-1 | File "/usr/local/lib/python3.13/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
backend-1 | return view_func(request, *args, **kwargs)
backend-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/viewsets.py", line 125, in view
backend-1 | return self.dispatch(request, *args, **kwargs)
backend-1 | ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/views.py", line 515, in dispatch
backend-1 | response = self.handle_exception(exc)
backend-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/views.py", line 475, in handle_exception
backend-1 | self.raise_uncaught_exception(exc)
backend-1 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/views.py", line 486, in raise_uncaught_exception
backend-1 | raise exc
backend-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/views.py", line 512, in dispatch
backend-1 | response = handler(request, *args, **kwargs)
backend-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/mixins.py", line 82, in partial_update
backend-1 | return self.update(request, *args, **kwargs)
backend-1 | ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/mixins.py", line 68, in update
backend-1 | self.perform_update(serializer)
backend-1 | ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
backend-1 | File "/app/core/api/viewsets.py", line 567, in perform_update
backend-1 | return super().perform_update(serializer)
backend-1 | ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/mixins.py", line 78, in perform_update
backend-1 | serializer.save()
backend-1 | ~~~~~~~~~~~~~~~^^
backend-1 | File "/app/core/api/serializers.py", line 291, in save
backend-1 | return super().save(**kwargs)
backend-1 | ~~~~~~~~~~~~^^^^^^^^^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/serializers.py", line 205, in save
backend-1 | self.instance = self.update(self.instance, validated_data)
backend-1 | ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/serializers.py", line 1035, in update
backend-1 | instance.save()
backend-1 | ~~~~~~~~~~~~~^^
backend-1 | File "/app/core/models.py", line 467, in save
backend-1 | default_storage.save(file_key, content_file)
backend-1 | ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/django/core/files/storage/base.py", line 49, in save
backend-1 | name = self._save(name, content)
backend-1 | File "/usr/local/lib/python3.13/site-packages/storages/backends/s3.py", line 565, in _save
backend-1 | obj.upload_fileobj(content, ExtraArgs=params, Config=self.transfer_config)
backend-1 | ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/boto3/s3/inject.py", line 764, in object_upload_fileobj
backend-1 | return self.meta.client.upload_fileobj(
backend-1 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
backend-1 | Fileobj=Fileobj,
backend-1 | ^^^^^^^^^^^^^^^^
backend-1 | ...<4 lines>...
backend-1 | Config=Config,
backend-1 | ^^^^^^^^^^^^^^
backend-1 | )
backend-1 | ^
backend-1 | File "/usr/local/lib/python3.13/site-packages/botocore/context.py", line 123, in wrapper
backend-1 | return func(*args, **kwargs)
backend-1 | File "/usr/local/lib/python3.13/site-packages/boto3/s3/inject.py", line 675, in upload_fileobj
backend-1 | return future.result()
backend-1 | ~~~~~~~~~~~~~^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/s3transfer/futures.py", line 111, in result
backend-1 | return self._coordinator.result()
backend-1 | ~~~~~~~~~~~~~~~~~~~~~~~~^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/s3transfer/futures.py", line 287, in result
backend-1 | raise self._exception
backend-1 | File "/usr/local/lib/python3.13/site-packages/s3transfer/tasks.py", line 142, in call
backend-1 | return self._execute_main(kwargs)
backend-1 | ~~~~~~~~~~~~~~~~~~^^^^^^^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/s3transfer/tasks.py", line 165, in _execute_main
backend-1 | return_value = self._main(**kwargs)
backend-1 | File "/usr/local/lib/python3.13/site-packages/s3transfer/upload.py", line 796, in _main
backend-1 | client.put_object(Bucket=bucket, Key=key, Body=body, **extra_args)
backend-1 | ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/botocore/client.py", line 601, in _api_call
backend-1 | return self._make_api_call(operation_name, kwargs)
backend-1 | ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
backend-1 | File "/usr/local/lib/python3.13/site-packages/botocore/context.py", line 123, in wrapper
backend-1 | return func(*args, **kwargs)
backend-1 | File "/usr/local/lib/python3.13/site-packages/botocore/client.py", line 1074, in _make_api_call
backend-1 | raise error_class(parsed_response, operation_name)
backend-1 | botocore.exceptions.ClientError: An error occurred (XAmzContentSHA256Mismatch) when calling the PutObject operation: None

Bildschirmaufnahme.2025-07-20.um.13.12.07.mov

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions