You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Flaky functional tests: a node briefly misses a just-created index or collection #3121
Functional scenarios occasionally fail because a node does not see an index or a collection that was just created (or still sees one that was just reset), as if the cluster-wide index cache were briefly out of sync between nodes. Three occurrences since the first 2.61 beta, each passing on rerun:
Whether collection:create / index:create return before every node's cache is updated (cluster sync is asynchronous), which would make these scenarios inherently racy rather than the code wrong.
Outcome expected: either a fix (if a real cache inconsistency), or the scenarios made robust to the asynchronous sync, documented here.
Not a 2.61 regression. The index cache is synchronized across nodes by fire-and-forget broadcasts: ClientAdapter.createCollection updates the local cache and emits core:storage:collection:create:after, ClusterNode.onCollectionAdded publishes AddCollection without awaiting it (Publisher.send), and the API response goes back right away. A peer applies it when its subscriber gets to it (Subscriber.handleCollectionAddition). Same for index creation and index:mDelete (admin:resetDatabase). Nothing in this path changed in 2.61.
#3098's replaceIndexes is not involved: it only runs on a reload (cluster join, kuzzle:state:live, admin:refreshIndexCache). On the two 2026-11-02 failures (attempt 1 of runs 41410081963 and 41416369508), all three nodes were ready before cucumber started, the failures came 23 s and 94 s later, and no reload ran (refreshIndexCache is only called by features/CollectionLock.feature, the legacy suite never calls it). No cluster warning in the node logs either.
The functional tests go through nginx, which spreads consecutive requests of one scenario across the 3 nodes: collection:create answered by node A, then collection:list / updateMapping / index:create served by node B before B has applied A's broadcast. The window is a few milliseconds, so it shows up only under CI load. A client behind a load balancer can hit the same window in production.
(Side note, found while reading replaceIndexes: a collection removed then re-created while a reload reads storage is judged unchanged by reconcileCollections (cached before and after) and takes the stored state, which may predate the re-creation. Only during a reload, so not the cause here; to keep in mind.)
Options
Tests only: after a step that creates or deletes an index or a collection, wait until every node (direct ports 17511–17513) sees it. Fixes the flakes, no product change.
Product: when the local cache says an index or collection is missing (or exists) and the request would fail on it, check storage before failing, and fix the cache. A request on node B right after a creation on node A then succeeds. Costs one storage call on the error path only.
Activity
rolljee commentedon Nov 2, 2026
Analysis
Not a 2.61 regression. The index cache is synchronized across nodes by fire-and-forget broadcasts:
ClientAdapter.createCollectionupdates the local cache and emitscore:storage:collection:create:after,ClusterNode.onCollectionAddedpublishesAddCollectionwithout awaiting it (Publisher.send), and the API response goes back right away. A peer applies it when its subscriber gets to it (Subscriber.handleCollectionAddition). Same for index creation andindex:mDelete(admin:resetDatabase). Nothing in this path changed in 2.61.#3098's
replaceIndexesis not involved: it only runs on a reload (cluster join,kuzzle:state:live,admin:refreshIndexCache). On the two 2026-11-02 failures (attempt 1 of runs 41410081963 and 41416369508), all three nodes were ready before cucumber started, the failures came 23 s and 94 s later, and no reload ran (refreshIndexCacheis only called byfeatures/CollectionLock.feature, the legacy suite never calls it). No cluster warning in the node logs either.The functional tests go through nginx, which spreads consecutive requests of one scenario across the 3 nodes:
collection:createanswered by node A, thencollection:list/updateMapping/index:createserved by node B before B has applied A's broadcast. The window is a few milliseconds, so it shows up only under CI load. A client behind a load balancer can hit the same window in production.(Side note, found while reading
replaceIndexes: a collection removed then re-created while a reload reads storage is judged unchanged byreconcileCollections(cached before and after) and takes the stored state, which may predate the re-creation. Only during a reload, so not the cause here; to keep in mind.)Options
chore(release): 2.61.0-beta.4 [skip ci]
kuzzlebot commentedon Nov 2, 2026
🎉 This issue has been resolved in version 2.61.0-beta.4 🎉
The release is available on:
Your semantic-release bot 📦🚀
chore(release): 2.61.0-beta.6 [skip ci]