nextcloud/server · error · Sabre\DAV\Exception
400
400
Error message
An error occurred while reading headers of a part
What it means
While reading a part's header lines, any line without a ':' cannot be a header and is rejected with HTTP 400. The offending line is logged first ('Header missing ":" on bulk request: ...' in nextcloud.log), which tells you the exact malformed input.
Source
Thrown at apps/dav/lib/BulkUpload/MultipartRequestParser.php:181
/**
* Return the headers of a part of the multipart body.
*
* @throws Exception
* @throws BadRequest
* @throws LengthRequired
*/
private function readPartHeaders(): array {
$headers = [];
while (($line = fgets($this->stream)) !== "\r\n") {
if ($line === false) {
throw new Exception('An error occurred while reading headers of a part');
}
if (!str_contains($line, ':')) {
$this->logger->error('Header missing ":" on bulk request: ' . json_encode($line));
throw new Exception('An error occurred while reading headers of a part', Http::STATUS_BAD_REQUEST);
}
try {
[$key, $value] = explode(':', $line, 2);
$headers[strtolower(trim($key))] = trim($value);
} catch (\Exception $e) {
throw new BadRequest('An error occurred while parsing headers of a part', Http::STATUS_BAD_REQUEST, $e);
}
}
if (!isset($headers['content-length'])) {
throw new LengthRequired('The Content-Length header must not be null.');
}
// TODO: Drop $md5 condition when the latest desktop client that uses it is no longer supported.
if (!isset($headers['x-file-md5']) && !isset($headers['oc-checksum'])) {
throw new BadRequest('The hash headers must not be null.');
}View on GitHub (pinned to ecdeb153ff)
Solutions
- Open nextcloud.log and read the logged json_encode($line) entry; it shows the exact malformed line and its bytes
- Fix the client to emit one flat 'Header-Name: value\r\n' line per header, no folding, no bare lines
- Keep headers ASCII with a single colon; regenerate the payload with a maintained multipart library instead of string templates
Example fix
// before "X-File-Path: /a.txt\r\n" ." continued-wrongly\r\n" // continuation line has no ':' -> this error // after "X-File-Path: /a.txt\r\n" // one flat header per line only
Defensive patterns
Strategy: validation
Validate before calling
// Validate header lines before writing them into the part
foreach ($headers as $key => $value) {
if (!preg_match('/^[!#$%&\'*+.^_`|~0-9A-Za-z-]+$/', $key)) {
throw new \InvalidArgumentException("Invalid header name: {$key}");
}
} Prevention
- Emit one flat 'Header-Name: value\r\n' per line; no folding, no bare lines
- Check nextcloud.log for 'Header missing' entries - it logs the exact offending line
- Test custom clients against the MultipartRequestParser unit fixtures first
When it happens
Trigger: A bulk-upload part containing a header line that is not 'Key: value': a folded/continuation line starting with space or tab, a bare word, or a line whose colon was lost (often due to wrong line-ending handling splitting lines incorrectly).
Common situations: Hand-built multipart bodies; clients emitting RFC 7230 obs-fold style headers that arrive as continuation lines; charset corruption mangling the ':' byte; header names or values with control characters.
Related errors
- An error occurred while checking content
- Boundary not found where it should be.
- An error occurred while reading headers of a part
- The Content-Length header must not be null.
- The hash headers must not be null.
AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17).
Data as JSON: /api/errors/7ff273d2ae2eef9e.
Report an issue: GitHub.