nextcloud/server · warning · Sabre\DAV\Exception\Forbidden

Setting ACL is not supported on this node

Error message

Setting ACL is not supported on this node

What it means

Per-object ACLs inside app calendars are derived from the calendar's permissions and cannot be written: CalendarObject::setACL() always throws Sabre\DAV\Exception\Forbidden (HTTP 403), mirroring AppCalendar::setACL() one level up.

Source

Thrown at apps/dav/lib/CalDAV/AppCalendar/CalendarObject.php:61

			[
				'privilege' => '{DAV:}read',
				'principal' => $this->getOwner(),
				'protected' => true,
			]
		];
		if ($this->calendar->getPermissions() & Constants::PERMISSION_UPDATE) {
			$acl[] = [
				'privilege' => '{DAV:}write-content',
				'principal' => $this->getOwner(),
				'protected' => true,
			];
		}
		return $acl;
	}

	#[\Override]
	public function setACL(array $acl): void {
		throw new Forbidden('Setting ACL is not supported on this node');
	}

	#[\Override]
	public function getSupportedPrivilegeSet(): ?array {
		return null;
	}

	#[\Override]
	public function put($data): void {
		if ($this->backend instanceof ICreateFromString && $this->calendar->getPermissions() & Constants::PERMISSION_UPDATE) {
			if (is_resource($data)) {
				$data = stream_get_contents($data) ?: '';
			}
			$this->backend->createFromString($this->getName(), $data);
		} else {
			throw new Forbidden('This calendar-object is read-only');
		}
	}

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Perform sharing/permission changes in the providing app, never per-object over CalDAV
  2. Clients: skip ACL writes for objects whose parent is an app calendar; handle 403 as 'not supported'
  3. App developers: expose any per-object sharing model through the app's own API
Defensive patterns

Strategy: fallback

Validate before calling

if ($node instanceof \OCA\DAV\CalDAV\AppCalendar\CalendarObject) {
    return; // per-object ACL is fixed; skip the ACL request
}

Type guard

function hasFixedAcl(Sabre\DAV\INode $node): bool {
    return $node instanceof \OCA\DAV\CalDAV\AppCalendar\CalendarObject
        || $node instanceof \OCA\DAV\CalDAV\AppCalendar\AppCalendar;
}

Try / catch

try {
    $node->setACL($acl);
} catch (Sabre\DAV\Exception\Forbidden $e) {
    // per-object permissions are owned by the source app; ignore
}

Prevention

When it happens

Trigger: An HTTP ACL method request targeting an individual .ics object (calendars/<user>/<app-calendar>/<object>.ics) attempting to add or modify ACEs.

Common situations: Calendar clients or scripts trying per-object permission grants (e.g. sharing a single event) on app-backed calendars.

Related errors


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