Issue Description
Updating a contact that was created via JMAP (ContactCard/set) from a CardDAV client (DAVx5) fails with HTTP 412 and CARDDAV:no-uid-conflict. The href in the error is the same resource being PUT. Contacts created via CardDAV can be updated via CardDAV without this error.
JMAP stores the card UID as urn:uuid:. DAVx5 sends UID: without the urn:uuid: prefix. It looks like the server treats those as two different UIDs and reports a conflict against the existing JMAP card (or against the same href).
Expected Behavior
PUT updates the existing resource (200/204), UID treated as the same person whether or not it is prefixed with urn:uuid:.
Actual Behavior
Stalwart return 412 when trying to update an existing contact.
Reproduction Steps
-
Create a contact in a JMAP client (ContactCard/set) in the account’s default address book.
-
Confirm JMAP ContactCard/get shows something like:
id: ba
uid: urn:uuid:cddccf70-dc55-4cad-a171-f55f1c5c0162
addressBookIds: { “b”: true } -
Sync the same address book with DAVx5 (/.well-known/carddav → /dav/card//default).
-
Edit the contact on the phone (title/org) and sync.
DAVx5 PUTs to the discovered href with If-Match and a vCard 4 body whose UID is the bare UUID.
Relevant Log Output
Request:
PUT /dav/card/[email protected]/default/nNhLyd8baW
If-Match: "3496115365"
Content-Type: text/vcard; version=4.0
BEGIN:VCARD
VERSION:4.0
PRODID:+//IDN bitfire.at//DAVx5/4.5.19-ose ez-vcard/0.12.2
UID:cddccf70-dc55-4cad-a171-f55f1c5c0162
FN:John Doe
N:Doe;John;;;
ORG:ACME Inc;TechnicalDept
TITLE:Engineer
TEL;TYPE=cell:+156236549
GRAMGENDER:MASCULINE
REV:20260917T104932Z
END:VCARD
Response:
HTTP/1.1 412 Precondition Failed
Content-Type: application/xml; charset=utf-8
<?xml version="1.0" encoding="UTF-8"?>
<D:error xmlns:D="DAV:" xmlns:B="urn:ietf:params:xml:ns:carddav">
<B:no-uid-conflict>
<D:href>/dav/card/user%40example.com/default/nNhLyd8baW</D:href>
</B:no-uid-conflict>
</D:error>
DAVx5 then logs: Resource has been modified on the server before upload, ignoring. The edit never lands. JMAP clients keep showing the old card.
The conflict href is the PUT target itself, not a second file.
Stalwart Version
v0.16.x
Installation Method
Binary (Linux)
Database Backend
PostgreSQL
Blob Storage
PostgreSQL
Search Engine
PostgreSQL
Directory Backend
Internal
Additional Context
Control case (works)
A contact created on DAVx5 (UID minted by DAVx5, no urn:uuid: prefix) can be edited on the phone and the change appears in JMAP ContactCard/get. So CardDAV update in general works; the failure is specific to cards that originated from JMAP.
A second JMAP-created contact (different UID/href) failed the same way on PUT (412 + no-uid-conflict).
Notes:
RFC 6352 no-uid-conflict is for “this UID is already used by a different resource” or “overwrite would change the UID”. Same-href update with an equivalent UID should not hit it.
RFC 6350 UID may be a URN. Clients often omit urn:uuid:. Servers usually normalize before uniqueness checks.
Access log often records only the incoming PUT body (HTTP still 412). The condition is in the XML body, not a JMAP methodResponses error.
I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on
I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on
I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.
on