You've successfully subscribed to Nuvotex Blog
Great! Next, complete checkout for full access to Nuvotex Blog
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info is updated.
Billing info update failed.

Nextcloud - NativeReadStream excess data will be lost

Running nextcloud with smb as external files runs into an issue starting with some of the latest releases - we saw the issue first on release 21.0.1. This guide describes how to implement a workaround until an official fix is available.

Daniel Nachtrub
Daniel Nachtrub

Running nextcloud with smb as external files runs into an issue starting with some of the latest releases - we saw the issue first on release 21.0.1. This guide describes how to implement a workaround until an official fix is available.

You might have issues running one of the (currently) latest releases of nextcloud. The issue we're seeing occurs when accessing external files using the SMB (CIFS) module. Nextcloud clients shows "connection aborted" errors, browsers just abort the download.

Checking the nextcloud logs show something similar to this:

stream_copy_to_stream(): Icewind\\SMB\\Native\\NativeReadStream::stream_read - read 24095 bytes more data than requested (32287 read, 8192 max) - excess data will be lost at /var/www/html/3rdparty/sabre/http/lib/Sapi.php#113
error log

This indicates that at some place a buffer is exceeded and data cannot be copied into the destination and is therefore lost.

Digging into the code revealed, that the error message is thrown somewhere around a buffer copy using stream_copy_to_stream function which is considered native from an application perspective. The stream copy requests data from the source stream and copies this data to the destination stream - when the requested data exceeds the limit an error is thrown.

Nextcloud uses icewind SMB library for SMB access. As this error occurs on SMB sources, i've reviewed the library and found the ultimate issue of this error. The error itself is located in a class called StringBuffer at the read method.

	public function read(int $count): string {
		$chunk = substr($this->buffer, $this->pos, $this->pos + $count);
		$this->pos += strlen($chunk);
		return $chunk;
	}
stringbuffer-read (original)

The actual error is that the length of the returned substring is combined with the current position - which would be valid if it's an end-index for the read.

Fix for the issue

As it's just the length to be read, the fix is quite easy:

	public function read(int $count): string {
		$chunk = substr($this->buffer, $this->pos, $count);
		$this->pos += strlen($chunk);
		return $chunk;
	}
stringbuffer-read (fixed)

Just replace the length calculation with $count and everything is fine. I've created a pull request on github for the SMB library to get this fix hopefully applied soon.

Fix for nextcloud

If you're running into this issue on nextcloud, you'll want to fix StringBuffer also - the file is located here: /var/www/html/apps/files_external/3rdparty/icewind/smb/src/StringBuffer.php (assuming that the root of your installation is /var/www/html).

Linux

Daniel Nachtrub

Just some guy working with computers.