Notifications
Clear all

CardDAV PUT returns 500 (NPE in VCard.parseVCard) when PHOTO has no TYPE parameter — breaks macOS Contacts sync

1 Posts
1 Users
0 Reactions
56 Views
(@soniqsofteu)
New Member
Joined: 1 month ago
Posts: 1
Topic starter  

Environment: Carbonio CE 26.6.0 (carbonio-appserver 4.5.1, appserver-conf 4.27.13, Ubuntu 24.04). Client: macOS 26.5 Contacts (AddressBookCore removed link ).

Problem: A CardDAV PUT of a vCard whose PHOTO property carries no TYPE parameter fails with HTTP 500. Current macOS Contacts adds TYPE=JPEG for JPEG photos but omits the parameter entirely for PNG photos. Per RFC 2426 TYPE is optional, so the vCard is valid — but the server rejects it.

Impact is bigger than one contact. The client never gets a success, so it retries the same PUT every 30-60 minutes forever, and the failing upload aborts the sync session before the download step. The result is a mailbox that looks like "CardDAV is broken on macOS": new contacts created on other devices never reach the Mac. In our case the account had one contact with a PNG photo and the whole address book stopped syncing on macOS while iOS and Thunderbird worked fine. Recovering required removing and re-adding the account on the Mac, because the queued upload survives both editing the contact and toggling Contacts for the account.

Reproduce: PUT to /dav/<user>/Contacts/<uid>.vcf:

BEGIN:VCARD
VERSION:3.0
N:Doe;John;;;
FN:John Doe
PHOTO;ENCODING=b:iVBORw0KGgoAAAANSUhEUgAA... (PNG payload, no TYPE parameter)
END:VCARD
 
→ HTTP 500. The same vCard with PHOTO;ENCODING=b;TYPE=JPEG:... is accepted.

Server log (mailbox.log):

ERROR [qtp...] dav - error handling method PUT. Sending HTTP Error - StatusCode 500
java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because the return value
of "com.zimbra.cs.service.formatter.VCard$VCardProperty.getParamValue(String)" is null
at com.zimbra.cs.service.formatter.VCard.parseVCard(VCard.java:340)
at com.zimbra.cs.dav.resource.AddressObject.uploadToVCard(AddressObject.java:223)
at com.zimbra.cs.dav.resource.AddressObject.create(AddressObject.java:250)
at com.zimbra.cs.dav.resource.Collection.createVCard(Collection.java:180)
at com.zimbra.cs.dav.resource.AddressbookCollection.createItem(AddressbookCollection.java:93)
at com.zimbra.cs.dav.service.method.Put.handle(Put.java:38)
 

Cause and suggested fix  VCard.java line 340 calls .toUpperCase() on a value that is null when the parameter is absent. The very next lines already handle an empty suffix, so the guard looks like an oversight:

String typeParam = vcprop.getParamValue("TYPE");
String suffix = typeParam != null ? typeParam.toUpperCase() : "";
 

If a concrete subtype is needed, it can be detected from the decoded payload's magic bytes (\x89PNG, \xFF\xD8\xFF for JPEG).

I originally filed this on GitHub as <a id="base-ui-_r_2tjm_" class="text-accent hover:underline underline-offset-[1px] outline-none hide-focus-ring ring-focus rounded-r2" href=" removed link " target="_blank" rel="noopener noreferrer">zextras/carbonio-mailbox#1117 and it was closed automatically with a pointer to this forum, so I am reposting it here.


   
Quote