nextcloud/server · error · Sabre\DAV\Exception
Fail to read part's content.
Error message
Fail to read part's content.
What it means
readPartContent() calls stream_get_line($this->stream, $length) with the part's declared Content-Length; a false return means the underlying read itself failed (distinct from a clean short read, which is caught by the EOF check instead). Thrown as a generic Exception; inside parseNextPart() BulkUploadPlugin catches it, logs it, and answers HTTP 400 with the JSON of files written so far.
Source
Thrown at apps/dav/lib/BulkUpload/MultipartRequestParser.php:218
return $headers;
}
/**
* Return the content of a part of the multipart body.
*
* @throws Exception
* @throws BadRequest
*/
private function readPartContent(int $length): string {
if ($length === 0) {
$content = '';
} else {
$content = stream_get_line($this->stream, $length);
}
if ($content === false) {
throw new Exception("Fail to read part's content.");
}
if ($length !== 0 && feof($this->stream)) {
throw new Exception('Unexpected EOF while reading stream.');
}
// Read '\r\n'.
stream_get_contents($this->stream, 2);
return $content;
}
/**
* Compute the MD5 or checksum hash of the next x bytes.
* TODO: Drop $md5 argument when the latest desktop client that uses it is no longer supported.
*/
private function validateHash(int $length, string $fileMd5Header, string $checksumHeader): void {
if ($checksumHeader !== '') {View on GitHub (pinned to ecdeb153ff)
Solutions
- Check nextcloud.log for paired PHP I/O warnings at the same timestamp to identify the stream failure
- Retry the bulk upload with fewer/smaller files to see whether the failure is size- or load-dependent
- Fix whatever invalidated the stream resource (premature body close, temp file eviction, memory limit killing the wrapper)
Defensive patterns
Strategy: try-catch
Validate before calling
$body = $request->getBody();
if (!is_resource($body) || !is_readable($body)) {
throw new \RuntimeException('Request body stream is not readable');
} Try / catch
try {
[$headers, $content] = $parser->parseNextPart();
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
$response->setStatus(400);
$response->setBody(json_encode($writtenFiles, JSON_THROW_ON_ERROR));
return false;
} Prevention
- Avoid reading the body resource from multiple components concurrently
- Ensure temp files backing the body are not evicted mid-request (disk space)
- Distinguish this hard-read-error from 'Unexpected EOF' which indicates truncation instead
When it happens
Trigger: A hard read error on the request body stream at the part-content position: invalidated/closed resource, socket error, or stream wrapper failure while slurping the part bytes.
Common situations: Connection torn down mid-body with an RST; temp-file-backed body evicted or deleted under disk pressure; wrapper errors under memory limits.
Related errors
- An error occurred while checking content
- 500
- Boundary not found where it should be.
- An error occurred while reading headers of a part
- 400
AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17).
Data as JSON: /api/errors/7d7052d9c6f88853.
Report an issue: GitHub.