nextcloud/server · error · Forbidden

Permission denied to rename the trashbin

Error message

Permission denied to rename the trashbin

What it means

TrashbinHome::setName() throws Sabre\DAV\Exception\Forbidden: DAV renames are expressed as MOVE with a Destination header, and the 'trashbin' segment under the calendar home is a fixed system path derived from the principal URI. Any MOVE that would rename or relocate the trashbin collection itself returns HTTP 403.

Source

Thrown at apps/dav/lib/CalDAV/Trashbin/TrashbinHome.php:119

		return in_array($name, [
			RestoreTarget::NAME,
			DeletedCalendarObjectsCollection::NAME,
		], true);
	}

	#[\Override]
	public function delete() {
		throw new Forbidden('Permission denied to delete the trashbin');
	}

	#[\Override]
	public function getName(): string {
		return self::NAME;
	}

	#[\Override]
	public function setName($name) {
		throw new Forbidden('Permission denied to rename the trashbin');
	}

	#[\Override]
	public function getLastModified(): int {
		return 0;
	}

	#[\Override]
	public function propPatch(PropPatch $propPatch): void {
		throw new Forbidden('not implemented');
	}

	#[\Override]
	public function getProperties($properties): array {
		return [
			'{DAV:}resourcetype' => new ResourceType([
				'{DAV:}collection',
				sprintf('{%s}trash-bin', \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD),

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Exclude the trashbin from rename/move batches - its path is fixed
  2. To get data out of the trashbin, MOVE objects into trashbin/restore (restore); the collection itself stays put
  3. Treat a MOVE 403 on the trashbin as terminal, not retryable

Example fix

// before
MOVE /remote.php/dav/calendars/alice/trashbin
Destination: /remote.php/dav/calendars/alice/bin/
-> 403 Permission denied to rename the trashbin

// after: move objects, not the collection
MOVE /remote.php/dav/calendars/alice/trashbin/objects/event-42.ics
Destination: /remote.php/dav/calendars/alice/trashbin/restore/event-42.ics
Defensive patterns

Strategy: validation

Validate before calling

if (rtrim($moveSource, '/') === "/remote.php/dav/calendars/{$user}/trashbin") {
    return; // the trashbin collection cannot be renamed or relocated
}

Try / catch

try {
    $client->request('MOVE', $uri, null, $destination);
} catch (\Sabre\HTTP\ClientHttpException $e) {
    if ($e->getResponse()->getStatus() === 403 && str_ends_with(rtrim($uri, '/'), '/trashbin')) {
        return; // fixed system path: not renameable
    }
    throw $e;
}

Prevention

When it happens

Trigger: MOVE with a Destination header renaming /remote.php/dav/calendars/<user>/trashbin; drag-and-drop reorganization in a DAV browser; batch renamers that iterate all discovered collections.

Common situations: GUI DAV clients that permit renaming any collection node; scripts relocating subtrees after principal or instance migrations.

Related errors


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