Skip to content

Option to not advertise vCard 4.0 ( macOS Contacts rejects and stops sync) in supported-address-data #265

Description

@0x0f0f0f

Summary

SupportedAddressData::default() (crates/carddav/src/addressbook/prop.rs) advertises text/vcard 3.0 and 4.0, hardcoded.

Two consequences:

  • DAVx5 android app writes vCard 4.0 whenever the server advertises it with no user override.
  • 🤯 macOS Contacts' CardDAV client does not accept vCard 4.0 at all. It drops the card and marks the whole address-book sync as failed, then retries every few minutes forever.

This results in any contact created or edited on Android never appearing on the Mac, with no visible error in either client. Every server I've seen macOS Contacts work with (Nextcloud/sabre, Radicale, iCloud) ends up serving 3.0 to it.

Reproduce

  1. rustical 0.14.1, one address book, principal used by both DAVx5 (4.5.19-ose) and
    macOS 15.5 Contacts.
  2. Create a contact on Android. DAVx5 PUTs:
       BEGIN:VCARD
       VERSION:4.0
       PRODID:+//IDN bitfire.at//DAVx5/4.5.19-ose ez-vcard/0.12.1
       UID:…
       FN:…
       N:…;;;;
       TEL;TYPE=cell:+…
       REV:…
       END:VCARD
  1. On the Mac, /usr/bin/log show --info --debug --predicate 'process == "AddressBookSourceSync"':

    CardInfoFromVCardData(): Ignored vCard at <private> because it is an unsupported vCard version: "<private>"
    -_handleAddsOrModifies: could not parse vCard in <private>
    ### ERRORS REMAIN in sync. Not setting lastSyncDate. …
      "/carddav/principal/…/…/" = "Error Domain=CDXManager Code=7 \"Some server contacts could not be copied to this address book.\""
    

    The count of "Ignored vCard" lines equals the count of VERSION:4.0 rows in
    addressobjects; every 3.0 card syncs fine.

Proposal

A config option, default unchanged:

[carddav]
advertise_vcard4 = true   # set false when Apple clients share the address book

that drops the 4.0 entry from supported-address-data. RFC 6352 §6.2.2 only requires the
server to accept what it advertises, so 4.0 PUTs keep working; DAVx5 simply switches to
3.0 for new writes. It is a one-line change in SupportedAddressData plus config plumbing.

A fuller fix would be content negotiation — convert stored 4.0 to 3.0 when the client's
Accept asks for 3.0 (what sabre/dav does) — but that is a larger change and the flag
covers the common case.

Workaround used meanwhile

UPDATE addressobjects SET vcf = replace(vcf, 'VERSION:4.0', 'VERSION:3.0') WHERE deleted_at IS NULL AND vcf LIKE '%VERSION:4.0%';
unblocks the Mac (etag is sha256 of the vcf, so it refetches), but recurs on the next
Android write. Happy to send a PR for the flag if you'd take it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions