nextcloud/server · error · BadRequest

URI too long. Address book not created

Error message

URI too long. Address book not created

What it means

CardDavBackend::createAddressBook() validates the URI segment before insert: strlen($url) > 255 throws BadRequest('URI too long. Address book not created') (HTTP 400). The cap protects the oc_addressbooks.uri column (VARCHAR(255)) and URL routing. It applies to the collection URI segment, not to the display name.

Source

Thrown at apps/dav/lib/CardDAV/CardDavBackend.php:361

			return true;
		});
	}

	/**
	 * Creates a new address book
	 *
	 * @param string $principalUri
	 * @param string $url Just the 'basename' of the url.
	 * @param array $properties
	 * @return int
	 * @throws BadRequest
	 * @throws Exception
	 */
	#[\Override]
	public function createAddressBook($principalUri, $url, array $properties) {
		if (strlen($url) > 255) {
			throw new BadRequest('URI too long. Address book not created');
		}

		$values = [
			'displayname' => null,
			'description' => null,
			'principaluri' => $principalUri,
			'uri' => $url,
			'synctoken' => 1
		];

		foreach ($properties as $property => $newValue) {
			switch ($property) {
				case '{DAV:}displayname':
					$values['displayname'] = $newValue;
					break;
				case '{' . Plugin::NS_CARDDAV . '}addressbook-description':
					$values['description'] = $newValue;
					break;

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Generate a short URI (slug, hash, UUID) and carry the full name in {DAV:}displayname
  2. Check strlen($uri) <= 255 client-side before MKCOL
  3. When importing long-named books, map them to short ids like book-<n>

Example fix

// before
$uri = 'sales-emea-region-q3-merged-master-list-extended-edition-2026-final-version';
$backend->createAddressBook('principals/users/alice', $uri, $props); // 400 URI too long

// after
$uri = 'contacts-' . substr(sha1($name), 0, 8);
$backend->createAddressBook('principals/users/alice', $uri, ['{DAV:}displayname' => $name]);
Defensive patterns

Strategy: validation

Validate before calling

if (strlen($uri) > 255) {
    $uri = 'book-' . substr(sha1($uri), 0, 12); // keep the full name in displayname
}

Type guard

function isValidAddressBookUri(string $uri): bool
{
    return $uri !== '' && strlen($uri) <= 255;
}

Try / catch

try {
    $backend->createAddressBook($principalUri, $uri, $props);
} catch (\Sabre\DAV\Exception\BadRequest $e) {
    if (str_contains($e->getMessage(), 'URI too long')) {
        $backend->createAddressBook($principalUri, 'book-' . substr(sha1($uri), 0, 12), ['{DAV:}displayname' => $displayName]);
    }
}

Prevention

When it happens

Trigger: MKCOL under /addressbooks/users/<user>/ whose collection name exceeds 255 bytes; importers deriving the URI verbatim from a long display name; UTF-8 names that percent-encode past 255 bytes.

Common situations: Bulk imports of addressbooks named after org units or long descriptions; URI schemes that concatenate title plus UUID; test generators with random long strings.

Related errors


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