nextcloud/server · error · Sabre\DAV\Exception\BadRequest

The {http://nextcloud.com/ns}offset has illegal value

Error message

The {http://nextcloud.com/ns}offset has illegal value

What it means

Same guard as the limit filter but for {http://nextcloud.com/ns}offset: OffsetFilter::xmlDeserialize() requires parseInnerTree() to return an int or string and otherwise throws Sabre\DAV\Exception\BadRequest (HTTP 400). An empty <n:offset/> yields null and triggers it.

Source

Thrown at apps/dav/lib/CalDAV/Search/Xml/Filter/OffsetFilter.php:28

namespace OCA\DAV\CalDAV\Search\Xml\Filter;

use OCA\DAV\CalDAV\Search\SearchPlugin;
use Sabre\DAV\Exception\BadRequest;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;

class OffsetFilter implements XmlDeserializable {

	/**
	 * @param Reader $reader
	 * @throws BadRequest
	 * @return int
	 */
	#[\Override]
	public static function xmlDeserialize(Reader $reader) {
		$value = $reader->parseInnerTree();
		if (!is_int($value) && !is_string($value)) {
			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}offset has illegal value');
		}

		return (int)$value;
	}
}

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Drop the <n:offset> element when the offset is 0 or unneeded
  2. Otherwise send an explicit number: <n:offset>0</n:offset>
  3. Unit-test the generated XML for empty pagination elements before shipping the client

Example fix

// before
<n:offset/>

// after
<n:offset>0</n:offset>
Defensive patterns

Strategy: validation

Validate before calling

$xml = '';
if ($offset !== null && $offset > 0) {
    $xml .= '<n:offset>' . (int) $offset . '</n:offset>'; // omit for page 0
}

Type guard

function isValidOffset(mixed $offset): bool {
    return $offset === null || (is_int($offset) && $offset >= 0);
}

Try / catch

try {
    $client->request('REPORT', $calendarUri, $xmlBody);
} catch (\Sabre\Http\ClientException $e) {
    if ($e->getResponse()?->getStatus() === 400) { /* empty <n:offset/>: send integer or drop */ }
}

Prevention

When it happens

Trigger: Sending a search REPORT containing an empty <n:offset/> or an offset element wrapping child XML instead of a number.

Common situations: Pagination helper that renders offset unconditionally with a null value for page 0; clients upgraded from a format where offset defaulted to 0 when empty.

Related errors


AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17). Data as JSON: /api/errors/fffb66f2a2098d72. Report an issue: GitHub.