Contacts synchronization issue with nextcloud

REPRODUCIBILITY: Always, not synchronizing
OS VERSION: 5.1 (but occurred before)
HARDWARE: Xperia 10 III (but occurred on other phones)
UI LANGUAGE: French
REGRESSION: Not that i can think of

DESCRIPTION:

Phone contacts are not synchronizing with server (bidirectional sync).

PRECONDITIONS:

Nextcloud integration setup, and contacts included in sync

STEPS TO REPRODUCE:

  1. Try to synchronize, does not work. Well, of course, it does work on a fresh install. But it did happen that it no longer works in a working phone (my wife’s one). The usual course is that I delete the account, recreate and resynchronize from server, and it works for some time, until it no longer works

  2. So this time, i tried to dig more into it. In the traces, i get this in the traces :
    [D] unknown:0 - “If-Match” = ““0dc2c9e322d3d82336c5fc374251d71f””
    [D] unknown:0 - bool CardDav::upsyncUpdates(const QString&, const QListQtContacts::QContact&, const QListQtContacts::QContact&, const QListQtContacts::QContact&) ignored 0 spurious updates to addressbook: “/remote.php/dav/addressbooks/users//contacts/”
    [W] unknown:0 - void CardDav::upsyncResponse() error: QNetworkReply::NetworkError(UnknownContentError) ( 412 )
    [D] unknown:0 - “”
    [D] unknown:0 - “<d:error xmlns:d=“DAV:” xmlns:s=“http://sabredav.org/ns\“>”
    [D] unknown:0 - " <s:exception>Sabre\DAV\Exception\PreconditionFailed</s:exception>”
    [D] unknown:0 - " <s:message>An If-Match header was specified and the resource did not exist</s:message>”
    [D] unknown:0 - " <s:header>If-Match</s:header>"
    [D] unknown:0 - "</d:error>

My understanding is that the If-Match is there to prevent conflicting update. But here, it is treated as a fatal error, and no further sync is done. This prevents the whole syncing process from working.

So i guess the steps to reproduce would be :

  1. set up a clean account, clean phone, on a clean nextcloud 33 install (version not really relevant)
  2. create a contact, synchronize it on the phone
  3. put the phone in offline mode.
  4. alter the contact on the phone
  5. alter the contact on nextcloud
  6. put the phone back in online mode
  7. try to sync

EXPECTED RESULT:

Somewhat, a conflict should occur. Conflicts are always problematic to handle, but there’s nothing that can’t be done. A merge interface would be great, but that’s asking for a lot.
In all cases, it should not stop the other contacts from synchronizing, that’s a terrible issue.

ACTUAL RESULT:

No contact sync occurs at all.

MODIFICATIONS:

Nothing relevant.

ADDITIONAL INFORMATION:

This problem has existed for ages.

3 Likes

This seems to be the relevant bit.

Wikipedia says:

412 Precondition Failed
The server does not meet one of the preconditions that the requester put on the request header fields.

“If-Match” = ““0dc2c9e322d3d82336c5fc374251d71f””

Could this be the offending bit? And what string is that? The Carddav username or passwort? Also I wonder what’s up with the double double quotes there.

At the same time you collect relevant logs on the phone you also have to collect them on the server.

Didn’t notice the double quotes.

My understanding (but i clearly lack knowledge related to carddav) is that the If-Match is a condition for the update, ie, do the update if the contact matches that condition. It is probably a hash. A quick look from the RFC6352:

9.2. Avoiding Lost Updates

 When resources are accessed by multiple clients, the possibility of    clients overwriting each other's changes exists.  To alleviate this,    clients SHOULD use the If-Match request header on PUT requests with    the ETag of the previously retrieved resource data to check whether    the resource was modified since it was previously retrieved.  If a    precondition failure occurs, clients need to reload the resource and    go through their own merge or conflict resolution process before    writing back the data (again using the If-Match check).

I don’t know how the ETag is produced, but “0dc2c9e322d3d82336c5fc374251d71f” is clearly an ETag (not the password, would have recognized it and filtered it).

@dcaliste could probably tell more on this. As for the server, there’s nothing relevant in the production logs (maybe if i temporarily increase the level, i may see something, but from what i can guess 412 seems a legitimate answer, so no server side log by default).

1 Like

You’re right, the quoted string looks like an etag, used to identify concurrent changes. Basically : the contact on the phone is already on the server (it has an etag), but it was modified on device (the local database reports so). In a sync process, this contact is thus supposed to be sent to the server. Before being sent, its etag should be compared to the server one. If it matches, then, it was not modified on server and the device update should be propagated. If not, its a conflict and there should be an automatic policy (leave it inconsistent or prioritise device or server side). Here, the modified contact is sent, but rejected by the server because already modified there. So the logic on device is faulty and not handling the conflict policy properly.

Additionally, as noted, a sync failure on a single contact should not block the full sync.

All this is said within conditional form, because I actually don’t know the contact sync code. I’ve only worked extensively with the calendar one… Several years ago, I modified the calendar code to avoid single failure to stop the sync process. Maybe the contact code is in the same old state, I don’t know.

3 Likes

Thanks for the clarification. Will probably need to dig deeper into this, then.

I’m not sure I have the same issue, but I have the same problem. I set up Nextcloud on my vanilla device and couldn’t load any contacts.

1 Like

I ended setting the URL path of the address book and few days later I got all my contacts synchronised with my phone.

Other point I should check is if the /.well-known is correctly configured on my server.

1 Like

Same here. Although I suspect it just takes a long time (hours, not days) until all contacts are synched and the Contacts app “sees” them.

Same here. Only contacts missing, path to adress book is empty as on my Xperia. I don’t even have the option to add a new contact on the Jolla to nextcloud, it just shows phone to save it, while I see my addressbooks double on the Xperia (one with Nextcloud Logo, one with anothers symbol).

Oh, I sadly can’t remember the correct path and wasn’t able to find it with a websearch right now :frowning: .

/remote.php/dav/adressbooks/MyName/

would be the equivalent to

/remote.php/dav/calendars/MyName/

but that doesn’t work. Where’s the error? Calendars work…

I have /remote.php/dav/addressbooks/users/MyUsername/contacts

After sevral hours still no success. What’s your Nextcloud version?

@pherjung @ohnonot

I’m self-hosting Nextcloud 34.0.2. I don’t know what I changed, but the contacts got sync only few days and reboots after the modification.

I have 34.0.3, also selfhosted.

My instance shows a hint that I should add a server ID to my configuration because of multiple php version. I think I’ll need to check that.

Strange… Sync now works on Jolla Phone, but not on Xperia 10 III. I changed my account settings to https (didn’t had that before as my Nextcloud is just available in my local network and feared problems with the self-signed certificate) and ingnore ssl errors and also deleted the contacts path. Sync works now as expected on the new Jolla.

Now I need to find out how to add the certificate verification to the jolla (and if I need to do this double on SFOS and Android side)…