nextcloud/server · error · Sabre\DAV\Exception

Principal not found

Error message

Principal not found

What it means

SystemPrincipalBackend::getGroupMemberSet() (apps/dav/lib/DAV/SystemPrincipalBackend.php:142) throws \Sabre\DAV\Exception('Principal not found') when getPrincipalByPath() returns null for the requested system principal. System principals (like the system calendar or scheduling inboxes) are a fixed, enumerated set; asking for the member set of any path not exactly matching one of those known principals fails here.

Source

Thrown at apps/dav/lib/DAV/SystemPrincipalBackend.php:142

	 * @return array
	 */
	#[\Override]
	public function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
		return [];
	}

	/**
	 * Returns the list of members for a group-principal
	 *
	 * @param string $principal
	 * @return array
	 */
	#[\Override]
	public function getGroupMemberSet($principal) {
		// TODO: for now the group principal has only one member, the user itself
		$principal = $this->getPrincipalByPath($principal);
		if (!$principal) {
			throw new \Sabre\DAV\Exception('Principal not found');
		}

		return [$principal['uri']];
	}

	/**
	 * Returns the list of groups a principal is a member of
	 *
	 * @param string $principal
	 * @return array
	 */
	#[\Override]
	public function getGroupMembership($principal) {
		[$prefix, ] = \Sabre\Uri\split($principal);

		if ($prefix === 'principals/system') {
			$principal = $this->getPrincipalByPath($principal);
			if (!$principal) {

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Re-discover valid principal URIs with a PROPFIND on /remote.php/dav/principals/system/ (depth 1) and use exactly those.
  2. Clear stale cached principal paths on the client and re-run discovery.
  3. Verify the prefix: system principals live under principals/system/, not principals/users/.
  4. Confirm the requested feature actually exists in this server version (some system principals were added/renamed across versions).
Defensive patterns

Strategy: validation

Validate before calling

// resolve via discovery instead of assuming a URI exists
$principals = $backend->getPrincipalsByPrefix('principals/system');
$valid = array_column($principals, 'uri');
if (!in_array($principalUri, $valid, true)) {
    $this->skip('Unknown system principal: ' . $principalUri);
    return [];
}

Type guard

function isKnownSystemPrincipal(array $validUris, string $uri): bool {
    return in_array(rtrim($uri, '/'), $validUris, true);
}

Try / catch

try {
    $members = $backend->getGroupMemberSet($principalUri);
} catch (\Sabre\DAV\Exception $e) {
    if (str_contains($e->getMessage(), 'Principal not found')) {
        $members = []; // skip stale/malformed system principal URIs
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: A DAV client or Sabre internal ACL check calling getGroupMemberSet() for a malformed or nonexistent system principal path, e.g. principals/system/typo or a principals/groups/... URI routed to this backend after a path/prefix change.

Common situations: Client caches holding old principal URIs across server upgrades; typos in constructed URLs; refactoring that changed principal prefixes; tools enumerating 'principals/system' children with wrong casing.

Related errors


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