Hi Couchbase team,
We upgraded Couchbase Lite Swift Enterprise from 3.2.4 to 4.0.2 . All of our local QA/testing passed, but we are seeing a production-only crash after the upgrade. The crash happens during collection.save(document:) on a background queue. We didn’t have these crashes with previous version.
Crashed: mainDatabaseQueue
0 libsystem_platform.dylib 0x930 _platform_memmove + 96
1 CouchbaseLiteSwift 0x10e888 fleece::smallVectorBase::_embiggen(unsigned long, unsigned long) + 85 (SmallVectorBase.hh:85)
2 CouchbaseLiteSwift 0x286cd0 fleece::impl::Encoder::placeItem() + 54 (SmallVectorBase.hh:54)
3 CouchbaseLiteSwift 0x2877d0 unsigned char* fleece::impl::Encoder::placeValue(unsigned long) + 221 (Encoder.cc:221)
4 CouchbaseLiteSwift 0x2875f4 fleece::impl::Encoder::writeData(fleece::impl::internal::tags, fleece::slice) + 240 (Encoder.cc:240)
5 CouchbaseLiteSwift 0x289104 fleece::impl::Encoder::writeKey(fleece::slice) + 619 (Encoder.cc:619)
6 CouchbaseLiteSwift 0x28cb64 FLEncoder_WriteKey + 510 (variant:510)
7 CouchbaseLiteSwift 0x1ccee0 litecore::VectorRecord::encodeBodyAndExtra(FLEncoder*) + 599 (Fleece.hh:599)
8 CouchbaseLiteSwift 0x1ccdf8 litecore::VectorRecord::encodeBodyAndExtra() + 416 (Fleece.hh:416)
9 CouchbaseLiteSwift 0x1ccaf0 litecore::VectorRecord::save(litecore::ExclusiveTransaction&, litecore::HybridClock&) + 227 (slice.hh:227)
10 CouchbaseLiteSwift 0x1b4f60 litecore::VectorDocument::save(unsigned int) + 657 (VectorDocument.cc:657)
11 CouchbaseLiteSwift 0x1b578c litecore::VectorDocument::saveIfRequested(C4DocPutRequest const&, C4Error*) + 502 (VectorDocument.cc:502)
12 CouchbaseLiteSwift 0x1b54cc litecore::VectorDocument::putNewRevision(C4DocPutRequest const&, C4Error*) + 396 (VectorDocument.cc:396)
13 CouchbaseLiteSwift 0x18aadc C4Document::update(fleece::slice, unsigned char) const + 200 (c4Document.cc:200)
14 CouchbaseLiteSwift 0x16b848 c4doc_update + 170 (RefCounted.hh:170)
15 CouchbaseLiteSwift 0xbedd8 -[CBLCollection saveDocument:into:withBaseDocument:asDeletion:db:error:] + 635 (CBLCollection.mm:635)
16 CouchbaseLiteSwift 0xbeaec -[CBLCollection saveDocument:withBaseDocument:concurrencyControl:asDeletion:error:] + 583 (CBLCollection.mm:583)
17 CouchbaseLiteSwift 0xbdbd8 -[CBLCollection saveDocument:concurrencyControl:error:] + 377 (CBLCollection.mm:377)
18 CouchbaseLiteSwift 0x1aca0 Collection.save(document:) + 134 (Collection.swift:134)
19 InsideMaps 0xc150a8 IMAbstractDAOCouch.saveLocallySync( 210 (IMAbstractDAOCouch.swift:210)
20 InsideMaps 0xc16730 @objc IMAbstractDAOCouch.saveLocallySync(+ 4379944752 (:4379944752)
21 InsideMaps 0x1057dd4 closure #1 in closure #1 in IMDatabaseSyncManager.fetchPropertiesAsync() + 1250 (IMDatabaseSyncManager.swift:1250)
22 InsideMaps 0x9ff724 <deduplicated_symbol> + 4377753380
23 libdispatch.dylib 0x1adc _dispatch_call_block_and_release + 32
24 libdispatch.dylib 0x1b7fc _dispatch_client_callout + 16
25 libdispatch.dylib 0xa468 _dispatch_lane_serial_drain + 740
26 libdispatch.dylib 0xaf44 _dispatch_lane_invoke + 388
27 libdispatch.dylib 0x153ec _dispatch_root_queue_drain_deferred_wlh + 292
28 libdispatch.dylib 0x14ce4 _dispatch_workloop_worker_thread + 692
29 libsystem_pthread.dylib 0x13b8 _pthread_wqthread + 292
30 libsystem_pthread.dylib 0x8c0 start_wqthread + 8
Questions:
Are there stricter key/value validation rules in 4.x (e.g., invalid keys, null bytes, NaN, unsupported types) that could lead to this writeKey crash?
Is it data race problem?
Is this a known issue in 4.0.2 or addressed in a newer patch?
Any guidance on how to reproduce or harden against this would be appreciated.
Thanks!
jens
February 9, 2026, 6:23pm
2
This looks like a bug in our code. Is it reproducible? Can you tell us anything about the contents of the document or the circumstances under which it was saved?
Thanks for the quick response. It’s frequent and at scale in production since the upgrade. We don’t have a deterministic repro yet. It only appears in production after upgrading from 3.2.4 → 4.0.2. All QA tests pass. We can’t reproduce it on our own. In addition there are several different crashes too. Here are stack traces:
Crash example 1:
Crashed: mainDatabaseQueue
0 CouchbaseLiteSwift 0x2877d8 unsigned char* fleece::impl::Encoder::placeValue(unsigned long) + 222 (Encoder.cc:222)
1 CouchbaseLiteSwift 0x2875f4 fleece::impl::Encoder::writeData(fleece::impl::internal::tags, fleece::slice) + 240 (Encoder.cc:240)
2 CouchbaseLiteSwift 0x289104 fleece::impl::Encoder::writeKey(fleece::slice) + 619 (Encoder.cc:619)
3 CouchbaseLiteSwift 0x28cb64 FLEncoder_WriteKey + 510 (variant:510)
4 CouchbaseLiteSwift 0x1ccee0 litecore::VectorRecord::encodeBodyAndExtra(FLEncoder*) + 599 (Fleece.hh:599)
5 CouchbaseLiteSwift 0x1ccdf8 litecore::VectorRecord::encodeBodyAndExtra() + 416 (Fleece.hh:416)
6 CouchbaseLiteSwift 0x1ccaf0 litecore::VectorRecord::save(litecore::ExclusiveTransaction&, litecore::HybridClock&) + 227 (slice.hh:227)
7 CouchbaseLiteSwift 0x1b4f60 litecore::VectorDocument::save(unsigned int) + 657 (VectorDocument.cc:657)
8 CouchbaseLiteSwift 0x1b578c litecore::VectorDocument::saveIfRequested(C4DocPutRequest const&, C4Error*) + 502 (VectorDocument.cc:502)
9 CouchbaseLiteSwift 0x1b54cc litecore::VectorDocument::putNewRevision(C4DocPutRequest const&, C4Error*) + 396 (VectorDocument.cc:396)
10 CouchbaseLiteSwift 0x18aadc C4Document::update(fleece::slice, unsigned char) const + 200 (c4Document.cc:200)
11 CouchbaseLiteSwift 0x16b848 c4doc_update + 170 (RefCounted.hh:170)
12 CouchbaseLiteSwift 0xbedd8 -[CBLCollection saveDocument:into:withBaseDocument:asDeletion:db:error:] + 635 (CBLCollection.mm:635)
13 CouchbaseLiteSwift 0xbeaec -[CBLCollection saveDocument:withBaseDocument:concurrencyControl:asDeletion:error:] + 583 (CBLCollection.mm:583)
14 CouchbaseLiteSwift 0xbdbd8 -[CBLCollection saveDocument:concurrencyControl:error:] + 377 (CBLCollection.mm:377)
15 CouchbaseLiteSwift 0x1aca0 Collection.save(document:) + 134 (Collection.swift:134)
16 InsideMaps 0xc150a8 IMAbstractDAOCouch.saveLocallySync( + 210 (IMAbstractDAOCouch.swift:210)
17 InsideMaps 0xc16730 @objc IMAbstractDAOCouch.saveLocallySync( + 4376700720 (:4376700720)
18 InsideMaps 0x1057dd4 closure #1 in closure #1 in IMDatabaseSyncManager.fetchPropertiesAsync() + 1250 (IMDatabaseSyncManager.swift:1250)
19 InsideMaps 0x9ff724 <deduplicated_symbol> + 4374509348
20 libdispatch.dylib 0x1adc _dispatch_call_block_and_release + 32
21 libdispatch.dylib 0x1b7fc _dispatch_client_callout + 16
22 libdispatch.dylib 0xa468 _dispatch_lane_serial_drain + 740
23 libdispatch.dylib 0xaf44 _dispatch_lane_invoke + 388
24 libdispatch.dylib 0x153ec _dispatch_root_queue_drain_deferred_wlh + 292
25 libdispatch.dylib 0x14ce4 _dispatch_workloop_worker_thread + 692
26 libsystem_pthread.dylib 0x13b8 _pthread_wqthread + 292
27 libsystem_pthread.dylib 0x8c0 start_wqthread + 8
Crash example 2:
Crashed: mainDatabaseQueue
0 libsystem_kernel.dylib 0xb0cc __pthread_kill + 8
1 libsystem_pthread.dylib 0x7810 pthread_kill + 268
2 libsystem_c.dylib 0x77f64 abort + 124
3 libsystem_malloc.dylib 0x15a64 malloc_vreport + 892
4 libsystem_malloc.dylib 0x156dc malloc_report + 64
5 libsystem_malloc.dylib 0x9714 ___BUG_IN_CLIENT_OF_LIBMALLOC_POINTER_BEING_FREED_WAS_NOT_ALLOCATED + 76
6 CouchbaseLiteSwift 0x286128 fleece::impl::Encoder::reset() + 101 (SmallVectorBase.hh:101)
7 CouchbaseLiteSwift 0x28d4a8 FLEncoder_Finish + 280 (unique_ptr.h:280)
8 CouchbaseLiteSwift 0x1ccf34 litecore::VectorRecord::encodeBodyAndExtra(FLEncoder*) + 609 (Fleece.hh:609)
9 CouchbaseLiteSwift 0x1ccdf8 litecore::VectorRecord::encodeBodyAndExtra() + 416 (Fleece.hh:416)
10 CouchbaseLiteSwift 0x1ccaf0 litecore::VectorRecord::save(litecore::ExclusiveTransaction&, litecore::HybridClock&) + 227 (slice.hh:227)
11 CouchbaseLiteSwift 0x1b4f60 litecore::VectorDocument::save(unsigned int) + 657 (VectorDocument.cc:657)
12 CouchbaseLiteSwift 0x1b578c litecore::VectorDocument::saveIfRequested(C4DocPutRequest const&, C4Error*) + 502 (VectorDocument.cc:502)
13 CouchbaseLiteSwift 0x1b54cc litecore::VectorDocument::putNewRevision(C4DocPutRequest const&, C4Error*) + 396 (VectorDocument.cc:396)
14 CouchbaseLiteSwift 0x18aadc C4Document::update(fleece::slice, unsigned char) const + 200 (c4Document.cc:200)
15 CouchbaseLiteSwift 0x16b848 c4doc_update + 170 (RefCounted.hh:170)
16 CouchbaseLiteSwift 0xbedd8 -[CBLCollection saveDocument:into:withBaseDocument:asDeletion:db:error:] + 635 (CBLCollection.mm:635)
17 CouchbaseLiteSwift 0xbeaec -[CBLCollection saveDocument:withBaseDocument:concurrencyControl:asDeletion:error:] + 583 (CBLCollection.mm:583)
18 CouchbaseLiteSwift 0xbdbd8 -[CBLCollection saveDocument:concurrencyControl:error:] + 377 (CBLCollection.mm:377)
19 CouchbaseLiteSwift 0x1aca0 Collection.save(document:) + 134 (Collection.swift:134)
20 InsideMaps 0xc150a8 IMAbstractDAOCouch.saveLocallySync(
+ 210 (IMAbstractDAOCouch.swift:210)
21 InsideMaps 0xc16730 @objc IMAbstractDAOCouch.saveLocallySync(
+ 4345407280 (:4345407280)
22 InsideMaps 0x1057dd4 closure #1 in closure #1 in IMDatabaseSyncManager.fetchPropertiesAsync() + 1250 (IMDatabaseSyncManager.swift:1250)
23 InsideMaps 0x9ff724 <deduplicated_symbol> + 4343215908
24 libdispatch.dylib 0x1adc _dispatch_call_block_and_release + 32
25 libdispatch.dylib 0x1b7ec _dispatch_client_callout + 16
26 libdispatch.dylib 0xa468 _dispatch_lane_serial_drain + 740
27 libdispatch.dylib 0xaf44 _dispatch_lane_invoke + 388
28 libdispatch.dylib 0x153ec _dispatch_root_queue_drain_deferred_wlh + 292
29 libdispatch.dylib 0x14ce4 _dispatch_workloop_worker_thread + 692
30 libsystem_pthread.dylib 0x13b8 _pthread_wqthread + 292
31 libsystem_pthread.dylib 0x8c0 start_wqthread + 8
Key points:
Same syncing mechanism as in 3.2.4 (no concurrency model change).
The only functional change was updating deprecated APIs: we now use collection.save(document:) instead of database.save(document:).
The crash happens on a background queue during collection.save(document:).
Payloads are JSON‑backed models from server data, with nested dictionaries/arrays. We are serializing our models into MutableDocument and then saving this document
We understand the docs say no downgrade support between major versions (4.x → 3.x). However, we’re facing severe production issues after upgrading to 4.0.2 and want to ship a hotfix that downgrades to 3.3.1 .
We’re considering this approach to avoid forcing a clean install:
Ship an app update with CBL 3.3.1
On first launch, delete the existing 4.x database/collections
Recreate the database and repopulate from our backend sync
Would this be a safe/acceptable path, or are there still incompatibilities even if we delete the 4.x data files and rebuild? If not safe, is a full clean install the only supported downgrade option?
Also, are there any other recommended downgrade/workaround options we should consider?
Any guidance would be appreciated.