-
-
Notifications
You must be signed in to change notification settings - Fork 27
CardDAV Write Back Troubleshooting
Everything about diagnosing a write-back: what each result means, how to read the log, and what the two diagnostic tools are actually telling you.
This page is for the person running it. How the write mechanics work inside is on CardDAV write-back internals; the feature itself is on CardDAV contact sync.
A write-back can never lose an edit an analyst made.
The person's record in FreeITSM is saved first and completely. Sending the change onward to the address book happens afterwards and cannot undo it.
So every failure on this page has the same shape: the change is safe in FreeITSM, and something stopped it reaching the card. There is no failure mode where pressing Save loses your work because somebody else's server was having a bad day.
This is deliberate, and it is the reason the wording of every message starts with "Saved here, butβ¦". The first thing you need to know is that your work survived; what happened to the address book is the second sentence.
| Damages | Recoverable? | |
|---|---|---|
| A bad import | FreeITSM's copy | Yes β import again |
| A bad write-back | your address book | No. Not by us. |
That asymmetry is why write-back is cautious to the point of being fussy: it only touches five fields, only on contacts it imported, only when a human deliberately edited one, and it refuses outright rather than guessing. There is no bulk "put it all right" pass and there should never be one.
Every save that could have reached the address book produces exactly one of these. They appear as a message on screen and as a row on the History tab under Changes sent back.
The contact card was updated. The message names which details changed.
Somebody had already changed the same detail in the address book, and FreeITSM did not overwrite them.
π This is not a fault. It is the safety net doing exactly the job it exists for. If you find yourself trying to make refusals stop happening, step back β the refusal is protecting a value somebody else entered deliberately.
The message tells you their value. The log row goes further and records all three: what the card says now, what FreeITSM last imported, and what your analyst typed. That is usually enough to see at a glance who is right.
What to do: run an import. That brings their version in. Then look at the person again and decide β if FreeITSM's value was the correct one after all, edit it again and it will now go through, because there is no longer a disagreement.
FreeITSM could not reach the server, or the server said no. The message carries the reason, and the log row carries the server's own words.
Common causes, in rough order of likelihood:
| What you see | Almost always means |
|---|---|
| Could not connect | The server is down, the address has changed, or a firewall is in the way |
| 401 / authentication failed | See the Digest trap below before you touch the password |
| 403 / forbidden | The account is real but that address book is read-only for it |
| 404 / not found | The contact's card has been deleted or moved on the server |
| 412 | A rare timing case β somebody saved that card in the instant between FreeITSM reading it and writing it. Just try again |
The card already matched. Common and harmless β it usually means an analyst pressed Save without actually changing any of the five details, or re-typed the same value.
It is logged as Nothing to send rather than Written on purpose: a log full of successes that wrote nothing would make a broken write-back look busy.
A stock Baikal server β the most common sabre/dav install, and what most people asking for CardDAV are running β ships with Digest authentication.
Basic authentication against it returns a flat 401, which looks exactly like a wrong password. The natural response is to go and check the password, find it is correct, check it again, and conclude FreeITSM is broken.
Measured against Baikal 0.12.1:
| FreeITSM's auth setting | Result |
|---|---|
| Basic | 401 |
| Digest | 207 (works) |
| Automatic | 207 (works) |
So: leave the authentication setting on Automatic unless you have a specific reason not to. If you have pinned it to Basic and are getting 401s, that is your answer.
Both the connection test and D015 report which scheme the server actually offered, so you never have to guess. That single line is usually the whole diagnosis.
System β Authentication β your address book β Configure β History tab β Changes sent back
Every attempt, newest first, whether it worked or not.
| Column | What it tells you |
|---|---|
| When | In your own timezone |
| Person | Kept even if the person is later deleted, so the row still makes sense |
| Result | One of the four above |
| Changed | Which details were actually written |
| Detail | FreeITSM's conclusion in plain English, plus an expandable "What the server said" |
Expanding What the server said (HTTP nnn) shows the server's reply word for word, not a tidied-up version.
That is deliberate and it is the most useful thing on the page. When an address book refuses something, the actual reason is in its own error body β and FreeITSM's paraphrase of it is no use whatsoever for diagnosing a server that FreeITSM cannot log into and you may not administer either. If you are sending a problem to whoever runs the CardDAV server, that block is the thing to send them.
The log is also the honest answer to "is this working?". A healthy one is mostly Written with the occasional Refused. Patterns worth noticing:
- All Refused β your import is stale. Something else is maintaining those contacts and FreeITSM has not read them recently. Import more often.
- All Failed with the same message β a configuration problem, not a data one. Go to D015.
- Nothing at all, ever β nothing has been attempted. Either write-back is off, nobody has edited one of the five fields, or the contacts are missing their card reference (D015 counts these).
System β Debug Tools β D015
Answers "does this connection work, right now?" It contacts the server, and it writes nothing.
It walks the path a real write-back takes, one rung at a time, because they fail for completely different reasons. Being told only "it does not work" leaves you four separate things to check; this tells you which one.
Reports the HTTP status and, crucially, which authentication scheme the server offered. See the Digest trap above.
If this fails, nothing below it can be tested and the report says so. It is a network, address, or credentials problem.
Signing in successfully does not mean this account can read that particular book. This rung separates the two, and reports how many contacts, groups and tags are actually in it.
If this fails but rung 1 passed, the account is fine and the book is the problem β wrong book chosen, or no permission on it.
Asks the server what the account is allowed to do, and lists the privileges it grants.
π΄ It writes nothing to find this out. Proving write access by creating a contact and deleting it again is worse than it sounds β the delete can fail, and you are left with a contact called "FreeITSM test" in a real address book that somebody then has to explain.
Write-back switched ON, and the account cannot write.
This is the nastiest configuration, because everything looks fine. Analysts edit contacts, FreeITSM saves them perfectly, and every single change is refused by the server. Without D015 you would find out from the write log, one puzzled analyst at a time.
D015 calls it out in as many words. The fix is on the address book server β grant the account write access. Nothing in FreeITSM can work around a permission the server has not given.
It also names the harmless opposite: the account could write but write-back is off. That is a perfectly good setting and it says so rather than nagging.
Three numbers the server cannot tell you:
- People managed by this book β how many contacts became people here
- Missing a card URL β π΄ these cannot be written back at all
- Missing a version marker β same
Missing a card URL is the one to watch. Contacts imported before write-back existed never recorded which card was theirs, so FreeITSM does not know where to write. The fix is simply to run an import β every import records it from then on. If this number is not zero, that is why write-back is quietly doing nothing for those people.
System β Debug Tools β D016
Answers a different question: "do the two lists still agree?"
It compares every imported person against their card as it stands right now, detail by detail, with both values side by side. It is slower than the other tools because it has to read every card in the book β there is no way to ask a CardDAV server "which of these changed".
- Before switching write-back on. Existing drift is exactly what will cause refusals, so it is worth knowing what you are walking into.
- After an import that looked wrong.
- When somebody says a number is out of date and you need to know which side is stale.
- Periodically, if you want to know whether keeping the two in step is worth the trouble at all.
| Section | Meaning |
|---|---|
| In step | Person and card agree on all five details |
| Disagreeing | Both values shown, FreeITSM's first, the card's second |
| No longer on the server | Their card has gone. FreeITSM never deletes anybody β the import marks people as left after the configured number of missed runs |
| On the server but not here | Usually correct: they are outside the group or tag you chose to import |
| Missing a card URL | As in D015 β write-back cannot reach these until the next import |
An empty value is printed as (empty) rather than left blank, so "they have no mobile" is never confused with "the report ran out of room".
D016 finishes with which details drift most, across everybody.
β That number is genuinely hard to get any other way, and it is the honest evidence for whether two-way sync earns its keep β and for which fields. If the answer turns out to be "phone numbers drift constantly and job titles never do", that tells you something real about how your organisation works, measured rather than guessed.
Deliberate, and it will stay that way.
Which side is right is a judgement. The card might be stale because nobody has updated it since somebody left; FreeITSM's copy might be stale because an analyst typed a number wrong. A single button that reconciles hundreds of contacts in one direction is precisely how a careful integration turns into a data-loss incident β and, per the asymmetry at the top of this page, in the direction we cannot undo.
Drift is exactly what makes a later write-back get refused. If D016 shows a person disagreeing and you then edit that same detail in FreeITSM, it will not be written β FreeITSM will not overwrite a value it did not last import.
So the order is: import first, then edit.
| What you are seeing | Start here |
|---|---|
| "Is it even trying?" | Write log. No rows at all = nothing attempted |
| Every save says Failed | D015 rung 1 or 2 |
| Every save says Refused | Import first. Then D016 to see how far apart they are |
| 401, and the password is definitely right | The Digest trap. Set authentication back to Automatic |
| Saves succeed but the card never changes | D015 rung 4 β missing card URLs |
| Fields are greyed out and won't edit | Write-back is off, or you did not press Save after ticking it |
| Contacts imported that should not have | You are pointed at the wrong address book, or the scope is set to everything |
| It worked and now doesn't | Write log β the last successful row tells you when it changed |
Worth stating plainly, because each one is a thing people ask for.
- No scheduled write-back. Changes go when an analyst saves one, never as a sweep.
- No bulk reconcile. See D016 above.
- No deleting. FreeITSM never deletes a contact from your address book under any circumstances.
- No creating. A person created in FreeITSM does not become a new card. Write-back only updates contacts that were imported.
- No portal self-service write-back. A customer correcting their own details in the portal is still refused on an imported contact. That is the GDPR Article 16 case from #133 and it needs a decision about customers writing to your address book, not just wiring.
- CardDAV contact sync β the feature, and how to set it up
- CardDAV write-back internals β how it works inside, and why it refuses rather than guesses
- CardDAV import internals β the import half
- CalDAV and CardDAV β the original analysis, and CalDAV, which is not built
FreeITSM β an open-source IT Service Management platform Β· github.com/edmozley/freeitsm Β· MIT licence
- Installation
- β° Scheduled tasks (cron jobs)
- Architecture
- π§ͺ Developer tests
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- π Date & Time Formats
- Theming & Dark Mode
- ποΈ Recent β getting back to what you were doing
- β¨οΈ Command palette (βK)
- π Searching inside tickets
- π Attached documents
-
MobileβFriendly
- β³ π« Mobile: Tickets
- β³ π» Mobile: Assets
- β³ π Mobile: Calendar
- β³ π Mobile: Knowledge
- β³ π¦ Mobile: Service Status
- β³ πΌ Mobile: Watchtower
- β³ π§© Mobile: Problem Management
- β³ π Mobile: Change Management
- β³ πΏ Mobile: Software
- β³ β Mobile: Tasks
- β³ π Mobile: Forms
- β³ π Mobile: Contracts
- β³ π Mobile: Domains
- β³ π Mobile: People
- β³ π Mobile: LMS
- β³ πΊοΈ Mobile: CMDB
- β³ πΊοΈ Mobile: Network Mapper
- β³ π§ Mobile: Process Mapper
- β³ βοΈ Mobile: Workflow
- β³ π₯οΈ Mobile: System
- β³ π Mobile: Reporting
- β³ π Mobile: System Wiki
- β³ π Mobile: Self-Service Portal
- β³ π§° Mobile: Techniques & Tricks
-
Security
- Layer 1 β which modules you can enter
- β³ π§© Module Access Control
- β³ π οΈ Module Access β Developer Guide
- Layer 2 β what you can administer
- β³ π Roles & Permissions
- β³ π οΈ Roles β Developer Guide
- β³ π€ Why capabilities are constants
- Layer 3 β the System module
- β³ π Admin Access Control
- Hardening
- β³ π Security review response 2026-08
- β³ π‘οΈ Security hardening 2026-08
- β³ π οΈ Security hardening 2026-08 β Developer Guide
- β³ π‘οΈ Round three β plain English
- β³ π οΈ Round three β Developer Guide
- β³ π‘οΈ CSRF protection (S4) β Developer Guide
- Single Sign-On (SSO)
- ποΈ LDAP & Active Directory
- π CardDAV contact sync
- Browser Extension
- API Reference
-
π REST API β how it works
- β³ π« REST API: Tickets
- β³ π» REST API: Assets
- β³ π΄ REST API: Problems
- β³ π REST API: Changes
- β³ π REST API: Knowledge
- β³ β REST API: Tasks
- β³ ποΈ REST API: CMDB
- β³ π REST API: Contracts
- β³ ποΈ REST API: Calendar
- β³ πΏ REST API: Software
- β³ π REST API: Domains
- β³ π¦ REST API: Service Status
- β³ βοΈ REST API: Morning Checks
- β³ π REST API: Forms
- β³ βοΈ REST API: Workflow
- β³ π·οΈ REST API: Cost centres
- β³ πΊοΈ REST API: Network Mapper
- β³ π§ Using the API docs page
- β³ π OpenAPI specification
- β³ β OpenAPI: kept correct
- β³ π οΈ Maintaining the catalogue
- Watchtower
-
Tickets
- β³ π Rota copy and paste β Developer Deep Dive
- β³ β Checklists & SOPs
- β³ βοΈ Mandatory fields
- β³ π·οΈ Ticket categories
- β³ π₯ Assigning tickets to a team, and escalation
- β³ π’ One board across every company
- β³ Mailbox Authentication
- β³ π€ Email send log
- β³ Basic IMAP mailboxes
- β³ Email rendering & images
- β³ SLA Management
- β³ WhatsApp channel
-
β³
βοΈ Telegram channel - β³ β CSAT company scope and filters β Developer Guide
- β³ π₯ Microsoft Teams channel
- β³ π¨οΈ Mattermost channel
- β³ π¬ Web chat channel
- β³ π£ Slack channel
- β³ π Linking tickets
- β³ β Record previews
- β³ π Ticket notes: internal or shared
- β³ ποΈ Canned responses
- β³ βοΈ Limiting replies to particular senders
- β³ π¨ Telling the analyst a ticket is theirs
- β³ βοΈ Email signatures
- β³ π The public web address
- β³ π’ Ticket numbering
- β³ π Raising a ticket for someone else
- β³ π Merging tickets
- β³ π Confidential tickets
- β³ π₯ Portal managers
- β³ π Who has seen a ticket
- β³ π Reading long tickets
- β³ β Splitting tickets
- β³ β Selecting several tickets
- β³ ποΈ The folder pane
- β³ π½ Just my tickets, or no closed ones
- β³ π οΈ Snoozing tickets β Developer Guide
- β³ π₯ Collision detection
- β³ β±οΈ Time tracking
- β³ π Scheduled work in your own calendar
- Problem Management
- Tasks
-
Assets
- β³ π’ Moving an asset between companies
- β³ π Shared asset locations
- β³ π§βπΌ Assigning assets to analysts
- β³ π Warranty and lease alerts
- β³ π Saved table views
- β³ π¨οΈ Recording anything, and importing it
- β³ π·οΈ QR asset labels
- β³ π Who holds what, and handover documents
- β³ π₯οΈ The inventory agent (PowerShell)
- β³ ποΈ Proxmox VE servers
- β³ βοΈ VMware Cloud Director servers
- β³ π Linking equipment to tickets
- β³ βοΈ Follow-up tasks on a ticket
- Knowledge
- Change Management
- Calendar
- Morning Checks
- Reporting
- Software
-
Forms
- β³ π¨ The form designer β Developer Guide
- β³ π Layout & the grid β Developer Guide
- β³ ποΈ Collections β grouping submissions
- β³ π Submissions as PDFs
- β³ β‘ What happens next β a form's own actions
- β³ π οΈ Sections & conditional logic β Developer Guide
- β³ π οΈ Lookup fields β Developer Guide
- β³ π‘οΈ Catalogue request approvals
- People
- Domains
- Contracts
- Service Status
- π Notifications
- π¨ War Room
- Self-Service Portal
- LMS
- Process Mapper
- CMDB
- Network Mapper
- Workflows
- Issue trackers (Jira, Azure DevOps)
- System
-
Overview
- β³ π Progress tracker
- β³ Concepts & vocabulary
- β³ Email routing & mailboxes
- β³ Settings: global vs per-company
- β³ Users & self-service
- β³ Staff cross-company access
- β³ π’ One board across every company
- β³ Worked examples
- β³ Pitfalls & gotchas
- β³ Scope: what it's for
- β³ π οΈ Developer Guide (make a module multi-company)
- β³ ποΈ Case study: CMDB (a linked graph)
- β³ π§ͺ Test harness (prove it's isolated)
- What this is
-
π Bugs resolved
- β³ π’ Chat tickets ignored your ticket numbering
- β³ π Dates shown as a dash, or in server time
- β³ π Assets β Users showed people from other companies
- β³ π Restricted analysts could read other modules' data
- β³ πΌοΈ Replies with a picture in the thread failed to send
- β³ π Reply attachments never reached the customer
- β³ π οΈ Outbound email attachments β Developer Guide
- β³ π A global SSO provider was missing from the portal
- β³ π Behind a proxy, the SSO redirect said http
- β³ βοΈ The portal tagline moved when you saved it
- β³ π¨ The portal settings screen forgot what you saved
- β³ π‘οΈ The approvals inbox said "Error" and nothing else
- β³ π A table's answers were missing from the PDF
- β³ β A single-select column let you tick every option
- β³ π The portal ignored a form's field widths
- β³ π The tasks board stopped taking clicks
- β³ ποΈ #121 The index list is out of date after upgrading
- β³ π #133 The calendar subscription was empty
- β³ π #131 Tasks always reopened on the board
- β³ π₯ #129 Every page returned HTTP 500 after upgrading
- β³ π³ #127 A PHP warning above the System page
- β³ π #126 Notes stamped with the server's clock
- β³ π Storing every date in UTC
- β³ πͺ The portal was down for everyone signed in
- β³ βοΈ #120 Workflow notes could never be written
- β³ βοΈ #123 Three errors when running Database Verification
- β³ π #122 The description box was a stub in the corner
- β³ π£ Demo data deleted real accounts
- β³ π #117 Sign-in redirected to the wrong address
- β³ π¨ #108 The priority dot was invisible
- β³ β±οΈ #116 Time logged from the right-click menu
- β³ π #114 API keys refused by our own guard
- β³ ποΈ #110 Assigning a task told nobody
- β³ πͺ #107 Signed out while still working
- β³ π #103 "Share with Requester" reached nobody
- β³ π #102 Search found nothing for hyphens
- β³ πͺ #101 Source code editor opened behind
- β³ βοΈ #88 Subtasks could not be ticked off
- β³ π» #84 Asset deep link selected nothing
- β³ π« #79 A new ticket arrived with no status
- β³ π§ #79 A ticket from email did not say so
- β³ π #78 Bell opened to nothing
- β³ π¬ #77 Mail only collected from Inbox
- β³ π #74 The default password could not be changed
- β³ π¦ #70 Renaming an impact level
- β³ π€ #67 App-only mailboxes could not send
- β³ π #45 Verify only ever worked for Microsoft
- β³ π #45 IMAP reported as not authenticated
- β³ βοΈ An email template stopped escaping itself
- β³ π The portal dashboard showed the wrong time
- β³ π’ The folder said 99 and the list showed 96