element-hq / element-hq/synapse
Unencrypted uploads larger than 2GB fail but the file is kept in the media_storage_path dir
- Dominant language
- Python
- Stars
- 4.6k
- Forks
- 600
- Avg merge
- 5d 22h
- Merged PRs (30d)
- 51
Description
This issue has been migrated from [#12023](https://github.com/matrix-org/synapse/issues/12023).
---
### Description
When uploading a file >= 2GB to an unencrypted room, the upload fails after the whole file has been transferred. The file is stored in media_storage_path, but is invisible to the client. Uploading unencrypted files >= 2GB is possible with Element, fails with nheko. Uploading files >= 2GB to encrypted rooms seems to fail before the file is actually transferred regardless of client, so won't lead to the issue described here.
### Steps to reproduce
- Set up matrix-synapse with nginx. Set max_upload_size = 10000M in homeserver.yaml and client_max_body_size 10000M in nginx conf
- Upload a file that's larger than 2GB
```
2022-02-17 17:33:30,131 - synapse.rest.media.v1.media_repository - 180 - INFO - POST-13679 - Stored local media in file '/var/lib/matrix-synapse/media/local_content/Zh/eF/VxQasjIpEYksYkggHXqV'
2022-02-17 17:33:30,134 - synapse.http.server - 100 - ERROR - POST-13679 - Failed handle request via 'UploadResource':
Traceback (most recent call last):
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/http/server.py", line 269, in _async_render_wrapper
callback_return = await self._async_render(request)
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/http/server.py", line 297, in _async_render
callback_return = await raw_callback_return
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/rest/media/v1/upload_resource.py", line 91, in _async_render_POST
content_uri = await self.media_repo.create_content(
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/rest/media/v1/media_repository.py", line 182, in create_content
await self.store.store_local_media(
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/storage/databases/main/media_repository.py", line 319, in store_local_media
await self.db_pool.simple_insert(
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/storage/database.py", line 931, in simple_insert
await self.runInteraction(desc, self.simple_insert_txn, table, values)
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/storage/database.py", line 743, in runInteraction
result = await self.runWithConnection(
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/storage/database.py", line 857, in runWithConnection
return await make_deferred_yieldable(
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/twisted/python/threadpool.py", line 244, in inContext
result = inContext.theWork() # type: ignore[attr-defined]
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/twisted/python/threadpool.py", line 260, in
inContext.theWork = lambda: context.call( # type: ignore[attr-defined]
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/twisted/python/context.py", line 117, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/twisted/python/context.py", line 82, in callWithContext
return func(*args, **kw)
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/twisted/enterprise/adbapi.py", line 282, in _runWithConnection
result = func(conn, *args, **kw)
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/storage/database.py", line 850, in inner_func
return func(db_conn, *args, **kwargs)
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/storage/database.py", line 609, in new_transaction
r = func(cursor, *args, **kwargs)
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/storage/database.py", line 945, in simple_insert_txn
txn.execute(sql, vals)
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/storage/database.py", line 310, in execute
self._do_execute(self.txn.execute, sql, *args)
File "/opt/venvs/matrix-synapse/lib/python3.9/site-packages/synapse/storage/database.py", line 343, in _do_execute
return func(sql, *args)
psycopg2.errors.NumericValueOutOfRange: value "2447099114" is out of range for type integer
LINE 1: ...ion/octet-stream', 1645173210131, 'testfile4.tar', '244709911...
```
Expected: The upload succeeds.
What happens instead: The upload fails, but the file is kept on the disk.
### Version information
If not matrix.org:
- **Version**: 1.52.0+bullseye1
- **Install method**:
apt matrix-synapse-py3 via https://packages.matrix.org/debian/
- **Platform**:
Debian 11 on a dedicated server
Contributor guide
Research direction
Start with synapse/rest/media/v1/upload_resource.py and media_repository.py, then follow the store_local_media call into synapse/storage/databases/main/media_repository.py and the PostgreSQL error shown in the traceback. Reproduce an unencrypted upload larger than 2GB with the stated limits; done means the upload succeeds and no inaccessible file remains in media_storage_path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nginx, postgresql, python
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100