nextcloud/server · warning · Sabre\DAV\Exception

Updating remote user principal is not supported

Error message

Updating remote user principal is not supported

What it means

RemoteUserPrincipalBackend::updatePrincipal() (apps/dav/lib/DAV/RemoteUserPrincipalBackend.php:70) unconditionally throws \Sabre\DAV\Exception when a PROPPATCH targets a federated remote user principal (principals/system/... remote-user collections). This backend resolves cloud IDs (federated users) read-only; their display name and properties live on the remote server, so local updates are architecturally impossible and rejected.

Source

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

			return null;
		}

		if (isset($this->principalsByPath[$path])) {
			return $this->principalsByPath[$path];
		}

		try {
			$principal = $this->principalUriToPrincipal($path);
		} catch (\Exception $e) {
			$principal = null;
		}
		$this->principalsByPath[$path] = $principal;
		return $principal;
	}

	#[\Override]
	public function updatePrincipal($path, \Sabre\DAV\PropPatch $propPatch) {
		throw new \Sabre\DAV\Exception('Updating remote user principal is not supported');
	}

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

	#[\Override]
	public function findByUri($uri, $principalPrefix) {
		if (str_starts_with($uri, 'principal:')) {
			$principal = substr($uri, strlen('principal:'));
			$principal = $this->getPrincipalByPath($principal);
			if ($principal !== null) {
				return $principal['uri'];
			}
		}

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Do not PROPPATCH remote user principals; restrict updates to local principals under principals/users/<uid>.
  2. Change a federated user's display name on their own server — the cloud ID display string is resolved from there.
  3. In client code, skip principals whose path contains the remote/system principal prefix before issuing PROPPATCH.
  4. If a client misbehaves, report/handle the 500 per Sabre semantics and continue with remaining principals instead of aborting the batch.
Defensive patterns

Strategy: validation

Validate before calling

// only PROPPATCH local user principals; never remote/system ones
if (preg_match('#^principals/(users|groups)/#', $principalUri)) {
    $backend->updatePrincipal($principalUri, $propPatch);
} else {
    $this->skip('Read-only principal: ' . $principalUri);
}

Type guard

function isLocalEditablePrincipal(string $uri): bool {
    return (bool)preg_match('#^principals/(users|groups)/[^/]+$#', $uri);
}

Try / catch

try {
    $backend->updatePrincipal($path, $propPatch);
} catch (\Sabre\DAV\Exception $e) {
    if (str_contains($e->getMessage(), 'not supported')) {
        $this->skip($path); // expected for read-only backends
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: A WebDAV PROPPATCH request (e.g. setting {DAV:}displayname) on a principal URI under the remote-users principal collection, typically issued by CalDAV/CardDAV clients or tooling that iterates all principals and attempts to edit them.

Common situations: Address-book/CardDAV clients trying to rename federated share contacts; automation scripts doing PROPPATCH over every principal returned by a principal-property-search; ACL managers attempting bulk property updates.

Related errors


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