nextcloud/server · error · DavException
Calendar is a subscription, not writable, shared or deleted
Error message
Calendar is a subscription, not writable, shared or deleted
What it means
DavException thrown by DefaultCalendarValidator::validateScheduleDefaultCalendar() when a Calendar node is unfit to be the default scheduling calendar. It rejects calendars that are webcal subscriptions (isSubscription()), not writable (canWrite() false, e.g. read-only share), shared (isShared()), or deleted/in trashbin (isDeleted()). Callers use it before storing IMip/scheduling invitations into the calendar.
Source
Thrown at apps/dav/lib/CalDAV/DefaultCalendarValidator.php:26
*/
namespace OCA\DAV\CalDAV;
use Sabre\DAV\Exception as DavException;
class DefaultCalendarValidator {
/**
* Check if a given Calendar node is suitable to be used as the default calendar for scheduling.
*
* @throws DavException If the calendar is not suitable to be used as the default calendar
*/
public function validateScheduleDefaultCalendar(Calendar $calendar): void {
// Sanity checks for a calendar that should handle invitations
if ($calendar->isSubscription()
|| !$calendar->canWrite()
|| $calendar->isShared()
|| $calendar->isDeleted()) {
throw new DavException('Calendar is a subscription, not writable, shared or deleted');
}
// Calendar must support VEVENTs
$sCCS = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
$calendarProperties = $calendar->getProperties([$sCCS]);
if (isset($calendarProperties[$sCCS])) {
$supportedComponents = $calendarProperties[$sCCS]->getValue();
} else {
$supportedComponents = ['VJOURNAL', 'VTODO', 'VEVENT'];
}
if (!in_array('VEVENT', $supportedComponents, true)) {
throw new DavException('Calendar does not support VEVENT components');
}
}
}
View on GitHub (pinned to ecdeb153ff)
Solutions
- Pick a personal, writable, non-deleted calendar as the scheduling default before validating.
- If the intended calendar is in the trashbin, restore it first and retry.
- Unshare or switch to a calendar the principal owns with write access.
- In code, pre-check $calendar->isSubscription() || !$calendar->canWrite() || $calendar->isShared() || $calendar->isDeleted() and fall back to creating a new personal calendar.
Example fix
// before
$validator->validateScheduleDefaultCalendar($calendar);
// after
if ($calendar->isSubscription() || !$calendar->canWrite() || $calendar->isShared() || $calendar->isDeleted()) {
$calendar = $calendarManager->createCalendar($userId, 'personal', ['VEVENT']);
}
$validator->validateScheduleDefaultCalendar($calendar); Defensive patterns
Strategy: validation
Validate before calling
if ($calendar->isSubscription() || !$calendar->canWrite() || $calendar->isShared() || $calendar->isDeleted()) {
// not usable as scheduling default; pick or create a personal writable calendar
$calendar = $calendarManager->createCalendar($userId, 'personal', ['VEVENT']);
}
$validator->validateScheduleDefaultCalendar($calendar); Try / catch
try {
$validator->validateScheduleDefaultCalendar($calendar);
} catch (\OCA\DAV\Connector\Sabre\Exception\DavException $e) {
// fall back to another calendar and retry validation
} Prevention
- Filter candidate calendars by canWrite()/isDeleted()/isShared()/isSubscription() before choosing a scheduling default.
- Restore trashed calendars before reusing them in scheduling flows.
- Cover this in tests with a read-only share fixture.
When it happens
Trigger: Passing a subscription, read-only shared, deleted, or otherwise non-writable Calendar to validateScheduleDefaultCalendar(); selecting such a calendar as scheduling default when an invite reply (IMip REPLY, accept/decline flow) arrives; trying to write scheduling objects into a calendar restored-preview from trashbin.
Common situations: User's default calendar was deleted so a fallback resolves to a shared/subscription calendar; admin moved users to read-only shares; automated tests that build Calendar fixtures without write permissions; calendar app picking the first calendar found which happens to be a webcal subscription.
Related errors
- Calendar does not support VEVENT components
- Calendar <$calendarId> is not writeable
- Could not create new calendar event: {message}
- Parameters missing in order to complete the request. Missing
- Parameters missing in order to complete the request. Missing
AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17).
Data as JSON: /api/errors/22a0da4d5fffb8f1.
Report an issue: GitHub.