nextcloud/server · warning · OCA\DAV\Connector\Sabre\Exception\TooManyRequests

Too many addressbooks created

Error message

Too many addressbooks created

What it means

CardDavRateLimitingPlugin counts MKCOL requests that create addressbooks (paths of exactly four segments starting with addressbooks/) per user in the app rate limiter: action 'carddav-create-address-book', budget dav rateLimitAddressBookCreation (default 10) per dav rateLimitPeriodAddressBookCreation seconds (default 3600). Exceeding the budget throws TooManyRequests (HTTP 429).

Source

Thrown at apps/dav/lib/CardDAV/Security/CardDavRateLimitingPlugin.php:68

		}
		$user = $this->userManager->get($this->userId);
		if ($user === null) {
			// We only care about authenticated users here
			return;
		}

		$pathParts = explode('/', $path);
		if (count($pathParts) === 4 && $pathParts[0] === 'addressbooks') {
			// Path looks like addressbooks/users/username/addressbooksname so a new addressbook is created
			try {
				$this->limiter->registerUserRequest(
					'carddav-create-address-book',
					$this->config->getValueInt('dav', 'rateLimitAddressBookCreation', 10),
					$this->config->getValueInt('dav', 'rateLimitPeriodAddressBookCreation', 3600),
					$user
				);
			} catch (RateLimitExceededException $e) {
				throw new TooManyRequests('Too many addressbooks created', 0, $e);
			}

			$addressBookLimit = $this->config->getValueInt('dav', 'maximumAdressbooks', 10);
			if ($addressBookLimit === -1) {
				return;
			}
			$numAddressbooks = $this->cardDavBackend->getAddressBooksForUserCount('principals/users/' . $user->getUID());

			if ($numAddressbooks >= $addressBookLimit) {
				$this->logger->warning('Maximum number of address books reached', [
					'addressbooks' => $numAddressbooks,
					'addressBookLimit' => $addressBookLimit,
				]);
				throw new Forbidden('AddressBook limit reached', 0);
			}
		}
	}

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Honor the 429: wait out the window (default 1 hour) or slow the creation rate
  2. Raise the budget: occ config:app:set dav rateLimitAddressBookCreation --value='100' and occ config:app:set dav rateLimitPeriodAddressBookCreation --value='3600'
  3. Fix the loop causing mass creation attempts - failed MKCOLs count too
  4. Spread automated creations across users or time

Example fix

# before
for i in $(seq 1 50): MKCOL /addressbooks/users/alice/book-$i/
-> 429 Too many addressbooks created

# after
occ config:app:set dav rateLimitAddressBookCreation --value='100'
for i in $(seq 1 50): MKCOL /addressbooks/users/alice/book-$i/  -> 201
Defensive patterns

Strategy: retry

Try / catch

try {
    $client->request('MKCOL', $uri);
} catch (\Sabre\HTTP\ClientHttpException $e) {
    if ($e->getResponse()->getStatus() === 429) {
        $wait = (int) ($e->getResponse()->getHeader('Retry-After')[0] ?? 3600);
        sleep(min($wait, 3600));
        $client->request('MKCOL', $uri); // single retry after the window
    }
}

Prevention

When it happens

Trigger: More than 10 MKCOL addressbook creations by the same user within one hour (defaults); provisioning scripts or test suites bulk-creating books; a sync client stuck recreating books in a loop.

Common situations: Automated onboarding creating one addressbook per team; CI running against a single test user; failed creations being retried immediately (each attempt still consumes budget).

Related errors


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