nextcloud/server · error · Forbidden

Calendar limit reached

Error message

Calendar limit reached

What it means

Also raised in RateLimitingPlugin::beforeBind, but by the hard cap check rather than the time-based limiter: before any calendar or subscription creation it counts the user's calendars (getCalendarsForUserCount) plus subscriptions (getSubscriptionsForUserCount) and, when the sum is already >= maximumCalendarsSubscriptions (default 30, -1 disables the check), throws a Sabre Forbidden (HTTP 403). The server logs a warning with the counts and limit before throwing.

Source

Thrown at apps/dav/lib/CalDAV/Security/RateLimitingPlugin.php:80

				);
			} catch (RateLimitExceededException $e) {
				throw new TooManyRequests('Too many calendars created', 0, $e);
			}

			$calendarLimit = $this->config->getValueInt('dav', 'maximumCalendarsSubscriptions', 30);
			if ($calendarLimit === -1) {
				return;
			}
			$numCalendars = $this->calDavBackend->getCalendarsForUserCount('principals/users/' . $user->getUID());
			$numSubscriptions = $this->calDavBackend->getSubscriptionsForUserCount('principals/users/' . $user->getUID());

			if (($numCalendars + $numSubscriptions) >= $calendarLimit) {
				$this->logger->warning('Maximum number of calendars/subscriptions reached', [
					'calendars' => $numCalendars,
					'subscription' => $numSubscriptions,
					'limit' => $calendarLimit,
				]);
				throw new Forbidden('Calendar limit reached', 0);
			}
		}
	}

}

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Delete or unsubscribe unused calendars/subscriptions to get below the cap (PROPFIND the calendar home to audit what exists)
  2. Raise the cap: occ config:app:set dav maximumCalendarsSubscriptions --value 100
  3. Set -1 to disable the cap entirely if the instance must allow unlimited calendars
  4. In client UIs, surface the limit clearly so users prune instead of retrying

Example fix

# before: default cap of 30
occ config:app:get dav maximumCalendarsSubscriptions
# (empty / 30)

# after: raise the cap
occ config:app:set dav maximumCalendarsSubscriptions --value 100
Defensive patterns

Strategy: validation

Validate before calling

# Count existing calendars+subscriptions before creating another
PROPFIND /remote.php/dav/calendars/alice/  (Depth: 1)
# -> count <d:response> entries with resourcetype calendar or subscription;
#    only issue MKCALENDAR when count < maximumCalendarsSubscriptions (default 30)

Try / catch

try {
    await client.mkCalendar(url);
} catch (e) {
    if (e.status === 403 && /Calendar limit reached/.test(e.message)) {
        // guide the user to delete calendars/subscriptions or raise the cap
        return promptUserToFreezeOrRaiseLimit();
    }
    throw e;
}

Prevention

When it happens

Trigger: Creating another calendar (MKCALENDAR on calendars/<user>/<name>) or a webcal subscription when the user already owns 30 or more calendars plus subscriptions combined; the rate-limit check passes first, then this absolute cap rejects the request.

Common situations: Long-lived accounts accumulating webcal subscriptions (subscriptions count toward the same cap); teams that lowered maximumCalendarsSubscriptions; import scripts assuming unlimited calendars; confusion because deleting only calendars while many subscriptions exist still trips the limit.

Related errors


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