nextcloud/server · warning · Sabre\DAV\Exception

Adding members to remote user is not supported

Error message

Adding members to remote user is not supported

What it means

RemoteUserPrincipalBackend::setGroupMemberSet() (apps/dav/lib/DAV/RemoteUserPrincipalBackend.php:110) unconditionally throws \Sabre\DAV\Exception. It implements Sabre's IPrincipalBackend contract, but group membership for a federated remote user cannot be modified locally: the remote user belongs to its own home server, and this backend models the user as a single-member 'group' (see getGroupMembership returning only the principal's own uri).

Source

Thrown at apps/dav/lib/DAV/RemoteUserPrincipalBackend.php:110

	#[\Override]
	public function getGroupMemberSet($principal) {
		return [];
	}

	#[\Override]
	public function getGroupMembership($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']];
	}

	#[\Override]
	public function setGroupMemberSet($principal, array $members) {
		throw new \Sabre\DAV\Exception('Adding members to remote user is not supported');
	}

	/**
	 * @return array{'{DAV:}displayname': string, '{http://nextcloud.com/ns}cloud-id': ICloudId, uri: string}
	 */
	private function principalUriToPrincipal(string $principalUri): array {
		[, $name] = \Sabre\Uri\split($principalUri);
		$cloudId = $this->cloudIdManager->resolveCloudId(base64_decode($name));
		return [
			'uri' => $principalUri,
			'{DAV:}displayname' => $cloudId->getDisplayId(),
			'{http://nextcloud.com/ns}cloud-id' => $cloudId,
		];
	}

	private function loadChildren(): void {
		$rows = $this->sharingMapper->getPrincipalUrisByPrefix('calendar', self::PRINCIPAL_PREFIX);
		$this->principals = array_map(

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Never attempt to modify members of remote user principals; membership is fixed (the user itself).
  2. Manage real groups via the local principals/users and groups backends or the provisioning API (OCS).
  3. Filter client-side: skip principals backed by RemoteUserPrincipalBackend (remote-user collections) when offering group editing.
  4. Treat the resulting 500 as 'not supported' and continue other work.
Defensive patterns

Strategy: validation

Validate before calling

// never call setGroupMemberSet on remote user principals
if (!str_contains($principalUri, 'remote') && isLocalGroupPrincipal($principalUri)) {
    $backend->setGroupMemberSet($principalUri, $members);
} else {
    $this->skip('Membership edits unsupported for ' . $principalUri);
}

Type guard

function supportsMemberSetEdit(string $principalUri): bool {
    return (bool)preg_match('#^principals/groups/[^/]+$#', $principalUri);
}

Try / catch

try {
    $backend->setGroupMemberSet($path, $members);
} catch (\Sabre\DAV\Exception $e) {
    if (str_contains($e->getMessage(), 'not supported')) {
        // expected for read-only backends: log and continue
        return;
    }
    throw $e;
}

Prevention

When it happens

Trigger: Any DAV operation that attempts to change the member set of a remote-user principal group — e.g. a CalDAV scheduling or ACL client issuing GROUP-MEMBER-SET PROPPATCH on principals/system/<base64-id>.

Common situations: Generic WebDAV admin tooling that walks all group principals and tries to synchronize members; clients implementing ACL group management blindly against every principal collection.

Related errors


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