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

Creating collections in address book objects is not allowed

Error message

Creating collections in address book objects is not allowed

What it means

HTTP 405 MethodNotAllowed from the final ExternalAddressBook::createDirectory(). Sabre calls createDirectory() on MKCOL targeting a child under the address book collection; app-generated external address books cannot contain child collections, so the request is always rejected.

Source

Thrown at apps/dav/lib/CardDAV/Integration/ExternalAddressBook.php:67

			$this->appId,
			$this->uri,
		]);
	}

	/**
	 * @inheritDoc
	 */
	#[\Override]
	final public function setName($name) {
		throw new DAV\Exception\MethodNotAllowed('Renaming address books is not yet supported');
	}

	/**
	 * @inheritDoc
	 */
	#[\Override]
	final public function createDirectory($name) {
		throw new DAV\Exception\MethodNotAllowed('Creating collections in address book objects is not allowed');
	}

	/**
	 * Checks whether the address book uri is app-generated
	 *
	 * @param string $uri
	 *
	 * @return bool
	 */
	public static function isAppGeneratedAddressBook(string $uri): bool {
		return str_starts_with($uri, self::PREFIX) && substr_count($uri, self::DELIMITER) >= 2;
	}

	/**
	 * Splits an app-generated uri into appId and uri
	 *
	 * @param string $uri
	 *

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Create regular address books with MKCOL on the address book home (/remote.php/dav/addressbooks/<user>/)
  2. Skip MKCOL under any address book whose URI starts with app-generated--
  3. Use occ dav:create-address-book for scripted creation

Example fix

// before: MKCOL under an external address book -> 405
await mkcol(`/remote.php/dav/addressbooks/${uid}/app-generated--myapp--team/extra/`);
// after: create collections only on the address book home
if (!bookUri.startsWith('app-generated--')) {
  await mkcol(`/remote.php/dav/addressbooks/${uid}/${newUri}/`);
}
Defensive patterns

Strategy: validation

Validate before calling

// client: never MKCOL under an external address book
function assertMkcolTarget(parentBookUri) {
  if (parentBookUri.startsWith('app-generated--')) {
    throw new Error('external address books do not accept sub-collections');
  }
}

Prevention

When it happens

Trigger: MKCOL against /remote.php/dav/addressbooks/<user>/app-generated--<appId>--<uri>/<child>/ by a client that creates sub-collections during sync or provisioning.

Common situations: Contact sync clients mirroring local folder trees into DAV; scripts that MKCOL defensively before writing vCards.

Related errors


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