nextcloud/server · error · Sabre\DAV\Exception\NotFound
Card not found
Error message
Card not found
What it means
For federated requests (basic-auth user 'system' with a trusted-server shared secret, per isFederation()), SystemAddressbook::getChild() bypasses the enumeration policy and fetches the card row directly via getCard(). If no row matches the requested URI it throws NotFound('Card not found') (HTTP 404). Reaching this branch already proves federation auth succeeded; the 404 means the card genuinely does not exist locally.
Source
Thrown at apps/dav/lib/CardDAV/SystemAddressbook.php:208
foreach ($group->getUsers() as $groupUser) {
if ($groupUser->getBackendClassName() === 'Guests') {
continue;
}
$otherName = SyncService::getCardUri($groupUser);
if ($otherName === $name) {
return parent::getChild($name);
}
}
}
throw new Forbidden();
}
if (!$this->isFederation()) {
return parent::getChild($name);
}
$obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name);
if (!$obj) {
throw new NotFound('Card not found');
}
$carddata = $this->extractCarddata($obj);
if (empty($carddata)) {
throw new Forbidden();
} else {
$obj['carddata'] = $carddata;
}
return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
}
#[\Override]
public function getChanges($syncToken, $syncLevel, $limit = null) {
if (!$this->carddavBackend instanceof SyncSupport) {
return null;
}
if (!$this->isFederation()) {
return parent::getChanges($syncToken, $syncLevel, $limit);View on GitHub (pinned to ecdeb153ff)
Solutions
- On the remote side, treat the 404 as authoritative and prune the card from the federation cache
- Verify the requested URI matches what SyncService::getCardUri(<user>) produces on the local server
- If the user should exist, check they were not deleted and the card row exists in oc_cards for the system addressbook
Defensive patterns
Strategy: validation
Validate before calling
// remote-side: only GET cards that discovery still lists
$status = $client->propFindStatus($systemBookUri . '/' . urlencode($name));
if ($status === 404) {
$federationCache->prune($name);
return null;
} Try / catch
use Sabre\DAV\Exception\NotFound;
try {
$card = $systemAddressbook->getChild($name);
} catch (NotFound $e) {
$federationCache->prune($name); // card gone server-side: drop the cached URI
return null;
} Prevention
- Re-sync the system addressbook instead of trusting cached card URIs
- Build card URIs exactly like SyncService::getCardUri() does
- Treat federation 404s as authoritative removals, never as transient errors
When it happens
Trigger: A trusted remote server requesting a card URI that does not exist locally (user deleted, UID renamed, URI built with a different scheme); lookups issued after local user deletion while the remote cache is stale.
Common situations: Federated shares referencing removed users; remotes never refreshing their copy of the system addressbook; card URI generation differing between Nextcloud versions.
Related errors
- Card not found
- URI too long. Address book not created
- Unknown property: {property}
- Too many addressbooks created
- AddressBook limit reached
AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17).
Data as JSON: /api/errors/f90aceba9098ab11.
Report an issue: GitHub.