nextcloud/server · warning · InvalidArgumentException
Calendar <$calendarId> does not support exporting
Error message
Calendar <$calendarId> does not support exporting
What it means
InvalidArgumentException thrown by occ dav:export-calendar (apps/dav/lib/Command/ExportCalendar.php:70) when the resolved calendar object does not implement OCP\Calendar\ICalendarExport. Only Nextcloud's own CalDAV calendars (CalendarImpl) know how to serialize to iCal/jCal/xCal; calendars contributed by apps via the calendar registry may not support export.
Source
Thrown at apps/dav/lib/Command/ExportCalendar.php:70
#[\Override]
protected function execute(InputInterface $input, OutputInterface $output): int {
$userId = $input->getArgument('uid');
$calendarId = $input->getArgument('uri');
$format = $input->getOption('format');
$location = $input->getOption('location');
if (!$this->userManager->userExists($userId)) {
throw new InvalidArgumentException("User <$userId> not found.");
}
// retrieve calendar and evaluate if export is supported
$calendars = $this->calendarManager->getCalendarsForPrincipal('principals/users/' . $userId, [$calendarId]);
if ($calendars === []) {
throw new InvalidArgumentException("Calendar <$calendarId> not found.");
}
$calendar = $calendars[0];
if (!$calendar instanceof ICalendarExport) {
throw new InvalidArgumentException("Calendar <$calendarId> does not support exporting");
}
// construct options object
$options = new CalendarExportOptions();
// evaluate if provided format is supported
if (!in_array($format, ExportService::FORMATS, true)) {
throw new InvalidArgumentException("Format <$format> is not valid.");
}
$options->setFormat($format);
// evaluate if a valid location was given and is usable otherwise output to stdout
if ($location !== null) {
$handle = fopen($location, 'wb');
if ($handle === false) {
throw new InvalidArgumentException("Location <$location> is not valid. Cannot open location for write operation.");
}
foreach ($this->exportService->export($calendar, $options) as $chunk) {
fwrite($handle, $chunk);
}View on GitHub (pinned to ecdeb153ff)
Solutions
- Export only CalDAV-backed calendars (those visible under /remote.php/dav/calendars/<uid>/)
- For app-provided read-only calendars, use that app's own export if any
- Confirm the target with PROPFIND on the CalDAV home before choosing the uri argument
Defensive patterns
Strategy: type-guard
Validate before calling
$calendars = $calendarManager->getCalendarsForPrincipal('principals/users/' . $uid, [$uri]);
$exportable = array_filter($calendars, fn ($c) => $c instanceof \OCP\Calendar\ICalendarExport); Type guard
$isExportable = fn ($calendar): bool => $calendar instanceof \OCP\Calendar\ICalendarExport;
Try / catch
try { $command->run(...); }
catch (\InvalidArgumentException $e) {
if (str_contains($e->getMessage(), 'does not support exporting')) {
// target an app-internal export or a real CalDAV calendar
}
} Prevention
- Check for ICalendarExport before offering export in tooling
- Expect app/plugin calendars to be read-only presentation objects
- Verify the URI belongs to /remote.php/dav/calendars before exporting
When it happens
Trigger: occ dav:export-calendar alice <uri> where <uri> resolves to a plugin/external calendar (e.g. a read-only app calendar registered via ICalendarProvider) rather than a database-backed CalDAV calendar.
Common situations: App-provided calendars (birthday calendars from contacts apps, external app calendars); trying to export 'contact_birthdays'; custom apps registering ICalendar implementations without export support.
Related errors
- Calendar <$calendarId> doesn't support this function
- User <$userId> not found.
- Calendar <$calendarId> not found.
- Format <$format> is not valid.
- Location <$location> is not valid. Cannot open location for
AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17).
Data as JSON: /api/errors/d6a56809c3c5f97f.
Report an issue: GitHub.