nextcloud/server · error · InvalidArgumentException

Unable to fetch principal for user $user

Error message

Unable to fetch principal for user $user

What it means

Thrown by occ dav:list-calendar-shares when the user exists in the user backend but IPrincipalBackend::getPrincipalByPath('principals/users/<uid>') returns null. Unlike errors 302, this indicates a data inconsistency: the account row exists while the DAV principal row for it does not. The command aborts before collecting group/circle memberships or shares.

Source

Thrown at apps/dav/lib/Command/ListCalendarShares.php:65

		$this->addOption(
			'calendar-id',
			'',
			InputOption::VALUE_REQUIRED,
			'List only shares for the given calendar id id',
			null,
		);
	}

	#[\Override]
	protected function execute(InputInterface $input, OutputInterface $output): int {
		$user = (string)$input->getArgument('uid');
		if (!$this->userManager->userExists($user)) {
			throw new \InvalidArgumentException("User $user is unknown");
		}

		$principal = $this->principal->getPrincipalByPath('principals/users/' . $user);
		if ($principal === null) {
			throw new \InvalidArgumentException("Unable to fetch principal for user $user");
		}

		$memberships = array_merge(
			[$principal['uri']],
			$this->principal->getGroupMembership($principal['uri']),
			$this->principal->getCircleMembership($principal['uri']),
		);

		$shares = $this->mapper->getSharesByPrincipals($memberships, 'calendar');

		$calendarId = $input->getOption('calendar-id');
		if ($calendarId !== null) {
			$shares = array_filter($shares, fn ($share) => $share['resourceid'] === (int)$calendarId);
		}

		$rows = array_map(fn ($share) => $this->formatCalendarShare($share), $shares);

		if (count($rows) > 0) {

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Run `occ upgrade` to apply any pending migrations for dav
  2. Inspect the principal row: `SELECT * FROM oc_principals WHERE uri = 'principals/users/<uid>'`
  3. If using LDAP, re-sync users and have the user log in once so the principal is provisioned
  4. As a last resort on a dev instance, recreate the user after exporting their data
Defensive patterns

Strategy: validation

Validate before calling

php occ user:info "$uid" >/dev/null 2>&1 || exit 1
# principal sanity check before the shares command
php -r '
  $p = OC::$server->get(\OCA\DAV\DAV\PrincipalBackend::class)->getPrincipalByPath("principals/users/$argv[1]");
  exit($p === null ? 1 : 0);
' "$uid" || { echo "Principal missing for $uid — run occ upgrade" >&2; exit 1; }

Prevention

When it happens

Trigger: User record present but the DAV principals entry missing or mis-persisted (partially failed provisioning, interrupted dav migration, manually edited database, inconsistent restore); LDAP user known to the user backend but principal not created on first DAV touch.

Common situations: Database restored without the principals tables; an occ upgrade with pending dav app migrations was interrupted; user inserted directly via SQL; instance cloned between environments with diverging dav schema state.

Related errors


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