⚠️ This issue respects the following points: ⚠️
Bug description
When using Nextcloud with S3-compatible object storage that does not send the Connection: close HTTP header, all appdata file requests (avatars, previews, theming assets) experience a 60-second timeout before completing.
The issue occurs because Nextcloud's SeekableHttpStream wrapper relies on EOF (End-of-File) signals from the server to know when to stop reading. When the S3 provider sends all data but keeps the HTTP connection open (per HTTP/1.1 keep-alive default), PHP's feof() waits indefinitely for the server to close the connection. This eventually times out after default_socket_timeout (60 seconds by default).
What works:
- Regular file uploads/downloads via WebDAV (uses Sabre DAV in
3rdparty/ with direct S3 streams that don't depend on connection close signal, not affected)
- Object storage providers that send
Connection: close header (MinIO, AWS S3)
What doesn't work:
- Appdata file reads (avatars, previews, theming) from S3 providers without
Connection: close header
Root cause:
The SeekableHttpStream::stream_read() method calls fread($handle, $count) which can request more bytes than remain in the response (e.g., requesting 8192 bytes when only 84 bytes remain). When the server doesn't close the connection, fread() waits for the full $count bytes or timeout, whichever comes first.
Evidence:
Comparative HTTP response headers show that AWS S3 and MinIO include Connection: close, while some S3-compatible providers do not, resulting in the timeout behavior.
Steps to reproduce
- Configure Nextcloud to use S3-compatible object storage that does not send
Connection: close header in HTTP responses
- Configure
'objectstore' in config/config.php with the S3 provider credentials
- Access any appdata file via the web interface:
- Navigate to user avatar:
https://your-nextcloud/index.php/avatar/{username}/64
- Or access any page.
Expected behavior
Appdata files (avatars, previews, theming assets) should load instantly (under 1 second) regardless of whether the S3-compatible storage provider sends the Connection: close header or not.
The SeekableHttpStream wrapper should behave like Sabre DAV (in 3rdparty/) which calculates completion based on Content-Length and bytes read, rather than depending on the server to signal EOF via connection closure. This makes it compatible with all S3-compatible storage providers.
Nextcloud Server version
33
Operating system
None
PHP engine version
None
Web server
None
Database engine version
None
Is this bug present after an update or on a fresh install?
None
Are you using the Nextcloud Server Encryption module?
None
What user-backends are you using?
Configuration report
List of activated Apps
Nextcloud Signing status
Nextcloud Logs
Additional info
No response
Bug description
When using Nextcloud with S3-compatible object storage that does not send the
Connection: closeHTTP header, all appdata file requests (avatars, previews, theming assets) experience a 60-second timeout before completing.The issue occurs because Nextcloud's
SeekableHttpStreamwrapper relies on EOF (End-of-File) signals from the server to know when to stop reading. When the S3 provider sends all data but keeps the HTTP connection open (per HTTP/1.1 keep-alive default), PHP'sfeof()waits indefinitely for the server to close the connection. This eventually times out afterdefault_socket_timeout(60 seconds by default).What works:
3rdparty/with direct S3 streams that don't depend on connection close signal, not affected)Connection: closeheader (MinIO, AWS S3)What doesn't work:
Connection: closeheaderRoot cause:
The
SeekableHttpStream::stream_read()method callsfread($handle, $count)which can request more bytes than remain in the response (e.g., requesting 8192 bytes when only 84 bytes remain). When the server doesn't close the connection,fread()waits for the full$countbytes or timeout, whichever comes first.Evidence:
Comparative HTTP response headers show that AWS S3 and MinIO include
Connection: close, while some S3-compatible providers do not, resulting in the timeout behavior.Steps to reproduce
Connection: closeheader in HTTP responses'objectstore'inconfig/config.phpwith the S3 provider credentialshttps://your-nextcloud/index.php/avatar/{username}/64Expected behavior
Appdata files (avatars, previews, theming assets) should load instantly (under 1 second) regardless of whether the S3-compatible storage provider sends the
Connection: closeheader or not.The
SeekableHttpStreamwrapper should behave like Sabre DAV (in3rdparty/) which calculates completion based onContent-Lengthand bytes read, rather than depending on the server to signal EOF via connection closure. This makes it compatible with all S3-compatible storage providers.Nextcloud Server version
33
Operating system
None
PHP engine version
None
Web server
None
Database engine version
None
Is this bug present after an update or on a fresh install?
None
Are you using the Nextcloud Server Encryption module?
None
What user-backends are you using?
Configuration report
List of activated Apps
Nextcloud Signing status
Nextcloud Logs
Additional info
No response