skip to content

A replica reconnects after three weeks with an old syncCookie — what may an RFC 4533 server answer, and what must the replica then do?

level: seniorimportance: nice to knowfreq 26%

answer

  1. a cookie is a request, not a right
  2. deletion history is finite
  3. full refresh, not a retry
  4. present phase versus delete phase
  5. identity is the entryUUID, not the DN

basics

~20 s

The server may honour the old syncCookie and send a delta, or, at its discretion, answer e-syncRefreshRequired (4096), meaning the cookie is too stale to build a delta from and the replica must start a fresh session with no cookie and take a full refresh of the content.

solid answer

~50 s

Presenting a `syncCookie` is a request, not a right. The server decides whether it can still express the difference between that point and now; RFC 4533 leaves that judgement to the server rather than mandating a retention period. If it can, the session proceeds normally. If it cannot — typically because the record of what was deleted has been pruned — it returns `e-syncRefreshRequired (4096)` on the search result, and the client must discard its cookie and run a new Sync Operation with none, receiving the whole content. The replica then has to reconcile: entries it holds that the server never sent are gone. That is what the refresh stage's two forms exist for — a delete phase naming removed entries by `syncUUID`, or a present phase listing what still exists, distinguished by the `refreshDeletes` flag.

code

asn1 · 10 lines
asn1
-- Sync State Control (1.3.6.1.4.1.4203.1.9.1.2)
syncStateValue ::= SEQUENCE {
     state     ENUMERATED { present, add, modify, delete },
     entryUUID syncUUID,
     cookie    syncCookie OPTIONAL }

-- Sync Done Control (1.3.6.1.4.1.4203.1.9.1.3)
syncDoneValue ::= SEQUENCE {
     cookie         syncCookie OPTIONAL,
     refreshDeletes BOOLEAN DEFAULT FALSE }

go deeper

for a junior

Recall that a replica's saved marker can become too old to use, and that the fix is to fetch the whole copy again rather than to retry with the same marker.

for a middle

Explain that the server decides whether an old cookie is usable, what e-syncRefreshRequired (4096) obliges the client to do, and why deletions are the part that cannot be reconstructed.

for a senior

Show that you have planned for it: retention windows against real offline periods, a present phase costing content size rather than change size, and LDIF seeding when the link cannot carry a full refresh.

for a principal

The judgement is how much deletion history the estate keeps against how long its worst-connected replica stays away, and who pays for a full refresh when that bet is lost.

## What a cookie promises, and what it does not A `syncCookie` records a point in the server's change history for one content — one base DN, scope and filter. Handing it back asks the server to express everything that has happened since. That is a request the server may refuse. **RFC 4533 does not oblige a server to honour an arbitrarily old cookie**, and the reason is concrete: to tell a client which entries were *deleted* since a point in the past, the server needs a record of those deletions. That record is finite. Three weeks at sea can outlive it. ## e-syncRefreshRequired (4096) When the server is unwilling or unable to build the delta, it ends the search with `e-syncRefreshRequired (4096)`. The meaning is narrow and worth stating precisely: - It is **not** an authentication failure, and re-binding changes nothing. - It is **not** a transient busy condition; retrying with the same cookie will get the same answer. - It says: *start again with no cookie*. The client runs a new Sync Operation for the same content, takes the whole thing, and stores the fresh cookie that session ends with. The client can hint at its preference in advance: the Sync Request Control's `reloadHint` tells the server the client would rather be given a full reload than have the server work hard to synthesise a delta. ## The present phase and the delete phase A refresh has to convey two different facts: *these entries changed* and *these entries are gone*. RFC 4533 has two ways to convey the second, and the `refreshDeletes` flag on the Sync Done Control says which one the preceding messages used. | | `refreshDeletes` FALSE — present phase | `refreshDeletes` TRUE — delete phase | |---|---|---| | What the server sends | every entry still in the content, changed ones in full, unchanged ones marked present | only the changes, with removed entries named as deleted | | How the client finds deletions | anything it holds that was **not** named is deleted | it is told, explicitly | | Cost | proportional to content size | proportional to the change set | | Typical use | after a very old or unusable cookie | an ordinary incremental catch-up | Either way, entries can be named in bulk: a `syncIdSet` carries a set of `syncUUIDs` in one message instead of one message per entry, with its own `refreshDeletes` flag saying whether that set is a set of present entries or of deleted ones. For a roster of thousands of seafarers where twelve changed, that is the difference between a handful of messages and thousands. ## Why the identity is a syncUUID and not a DN Every entry in a synchronization session is identified by its `syncUUID`, the entry's `entryUUID (1.3.6.1.1.16.4)` — a fixed 16-octet value assigned when the entry is created and never reissued. - A DN is a **location**. Move a seafarer's entry from one organizational unit to another and the DN changes, while the person and the entry do not. - A `syncUUID` is an **identity**. It survives a rename or a move, so the client sees one entry that moved rather than a delete and an unrelated add. - The location is still available when the client needs it: `entryDN (1.3.6.1.1.20)` is the operational attribute that reports an entry's current DN. A client that keyed its local copy on the DN would, after a reorganisation ashore, hold a duplicate of every moved seafarer and no way to notice. ## What the vessel actually does when it docks 1. It opens a connection, performs an LDAP Bind operation, and issues the Sync Operation with `mode` `refreshOnly` and its three-week-old cookie. 2. If the server answers normally, it applies the changes, honours `refreshDeletes` one way or the other, and stores the new cookie. 3. If the server answers `e-syncRefreshRequired (4096)`, it discards the cookie, re-runs with none, and takes the full content — over a link that may be metered, which is exactly why this is an operational decision and not only a protocol one. The design consequence: a fleet with three-week offline windows either needs a server retention window wider than its worst voyage, or it needs to budget for periodic full refreshes and to seed new or hopelessly stale replicas from an LDIF bulk transfer rather than over the wire during a short port call. Deciding which is the choice, and pretending the cookie will always be honoured is what makes it a surprise.

  • Why can a server refuse an old cookie at all — what is it short of?
    The record of deletions. Sending changed entries only needs current content, but telling a client which entries vanished since an old point needs history of removals, and that history is pruned. Once it no longer reaches back to the cookie's point, the server cannot honestly describe the difference, so it asks for a full refresh instead of guessing.
  • What does reloadHint on the Sync Request Control express?
    The client's preference for being given a full reload rather than having the server work to produce an incremental result. It is a hint, not a demand: the server still decides. A client that knows it has been absent for weeks, or that has lost local state, can set it to save a pointless attempt at a delta.
  • When would you seed a replica with LDIF instead of letting the synchronization run?
    When the initial or full-refresh transfer is too large for the link or the window available — a new vessel replica, or one so stale the cookie is worthless. An LDIF bulk transfer can be carried by any means, loaded locally, and the synchronization session then started from that point, so the short port call carries only the delta.

saying these in an interview costs you the question

  • Treats e-syncRefreshRequired as a transient error worth retrying unchanged
  • Thinks re-authenticating clears a refresh-required condition
  • Assumes a server must honour a syncCookie of any age
  • Keys the local replica on the DN rather than on entryUUID
  • Reads refreshDeletes FALSE as meaning nothing was deleted
  • Believes a present phase and a delete phase can be mixed freely in one refresh