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
- Generate a short URI (slug, hash, UUID) and carry the full name in {DAV:}displayname
- Check strlen($uri) <= 255 client-side before MKCOL
- 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
- Derive addressbook URIs from slugs or ids, never raw display names
- Enforce the 255-byte cap client-side, measured on the percent-encoded URI
- Put human-readable names in {DAV:}displayname, not the URI segment
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
- Unknown property: {property}
- vCards on CardDAV servers MUST have a UID property
- vCard can not be empty
- Too many addressbooks created
- AddressBook limit reached
AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17).
Data as JSON: /api/errors/57cabb7c0eeec921.
Report an issue: GitHub.