Skip to content

Unread messages in a single conversation can not be marked as read on iPhone. #6147

@andrimarjonsson

Description

@andrimarjonsson
  • I have searched open and closed issues for duplicates
  • I am submitting a bug report for existing functionality that does not work as intended
  • This isn't a feature request or a discussion topic

Bug description

This started a few weeks ago when I received a text message that when I tried to read it, the app crashed. After that Signal would consistently crash every time I tried opening that specific conversation. Other conversations were unaffected.

In a desperate attempt to try and break the cycle I tried installing the desktop client on my laptop and linked it to the IOS app. It did not crash when entering the conversation but it also seems to have not migrated this message over.

A side effect of linking the desktop app now was that opening the conversation on IOS no longer crashes the app.

But now it seems I have a conversation in an inconsistent state that the app cannot update the unread count of. The only way to affect the unread count is to open it in the desktop app and then it only goes down to 2 as it would seem the desktop client has no knowledge of those corrupt messages in it's local database.

Now I did have a look myself at the logs and found two interesting sections. The first one is from the point in time where opening the conversation was crashing and it looks pretty straight forwards, i.e. the conversation is corrupted in the db.

2025/10/15 10:46:20:146  INF💛 [StorageService.swift:689 storageRequest(withMethod:endpoint:body:chatServiceAuth:)]: HTTP 204 <- SS GET v1/storage/manifest/version/362
2025/10/15 10:46:20:217  INF💛 [OWSChatConnection.swift:425 makeRequest(_:)]: HTTP 200 <- ID GET v2/keys […563]
2025/10/15 10:46:20:218  INF💛 [OWSChatConnection.swift:409 makeRequest(_:)]: Sending… -> ID GET v2/keys?identity=pni […813]
2025/10/15 10:46:20:315  INF💛 [MessageSendLog.swift:396 cleanUpExpiredEntries()]: Deleted 3 stale MSL entries
2025/10/15 10:46:20:365  INF💛 [OWSChatConnection.swift:425 makeRequest(_:)]: HTTP 200 <- ID GET v2/keys?identity=pni […813]
2025/10/15 10:46:20:471  INF💛 [SSKKeychainStorage.swift:106 removeValue(service:key:)]: Removing TSKeyChainService/TSDatabasePass
2025/10/15 10:46:20:474  INF💛 [SSKKeychainStorage.swift:106 removeValue(service:key:)]: Removing TSKeyChainService/OWSDatabaseCipherKeySpec
2025/10/15 10:46:21:415  ERR❤️ [MentionFinder.swift:80 messagesMentioning(aci:in:includeReadMessages:tx:)]: unexpected error SQLite error 11: database disk image is malformed - while executing `SELECT interaction.*
FROM model_TSInteraction as interaction

INNER JOIN model_TSMention as mention
    
    ON mention.uniqueMessageId = interaction.uniqueId
    AND mention.uuidString = ?
WHERE interaction.uniqueThreadId = ? AND interaction.read IS 0 AND interaction.isGroupStoryReply IS 0
ORDER BY id`
2025/10/15 10:46:21:459  ERR❤️ [OWSSwiftUtils.swift:67 owsFail(_:logger:file:function:line:)]: 0   SignalServiceKit                    0x…148 block_destroy_helper.16 + 96280
1   SignalServiceKit                    0x…04c block_destroy_helper + 96352
2   SignalServiceKit                    0x…f68 block_destroy_helper + 96124
3   SignalServiceKit                    0x…d40 block_destroy_helper.16 + 87056
4   SignalServiceKit                    0x…c64 swift_willThrowTyped + 27360
5   SignalServiceKit                    0x…5c8 swift_willThrowTyped + 13380
6   SignalServiceKit                    0x…418 swift_willThrowTyped + 12948
7   Signal                              0x…af8 Signal + 2632440
8   Signal                              0x…7e4 Signal + 2127844
9   Signal                              0x…964 Signal + 2128228
10  UIKitCore                           0x…6d0 xxxx-xx-xx-xxx744 + 16660176
11  UIKitCore                           0x…050 xxxx-xx-xx-xxx744 + 16658512
12  UIKitCore                           0x…94c xxxx-xx-xx-xxx744 + 16660812
13  UIKitCore                           0x…1e4 xxxx-xx-xx-xxx744 + 3195364
14  UIKitCore                           0x…714 xxxx-xx-xx-xxx744 + 2258708
15  UIKitCore                           0x…e54 xxxx-xx-xx-xxx744 + 1400404
16  UIKitCore                           0x…520 xxxx-xx-xx-xxx744 + 1402144
17  UIKitCore                           0x…6ec xxxx-xx-xx-xxx744 + 1402604
18  CoreFoundation                      0x…76c xxxx-xx-xx-xxxEE8 + 255852
19  CoreFoundation                      0x…974 xxxx-xx-xx-xxxEE8 + 63860
20  CoreFoundation                      0x…efc xxxx-xx-xx-xxxEE8 + 44796
21  CoreFoundation                      0x…174 CFRunLoopRunSpecific + 572
22  GraphicsServices                    0x…988 GSEventRunModal + 160
23  UIKitCore                           0x…a88 xxxx-xx-xx-xxx744 + 5134984
24  UIKitCore                           0x…f78 UIApplicationMain + 336
25  libswiftUIKit.dylib                 0x…ee4 $s5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGSgSSSgAJtF + 100
26  Signal                              0x…da4 Signal + 191908
27  dyld                                0x…4d0 start + 444
2025/10/15 10:46:21:459  ERR❤️ [SDSDatabaseStorage.swift:246 read(file:function:line:block:)]: error: SQLite error 11: Optional("database disk image is malformed") (extended result code: 11)
2025/10/15 10:46:22:862  WRN🧡 [AppDelegate.swift:186 application(_:didFinishLaunchingWithOptions:)]: Launching…
2025/10/15 10:46:22:872  INF💛 [DeviceTransferService+Restore.swift:298 launchCleanup()]: hasBeenRestored: false
2025/10/15 10:46:22:893  INF💛 [AppVersion.swift:253 dumpToLog()]: firstAppVersion: 5_47_0
2025/10/15 10:46:22:893  INF💛 [AppVersion.swift:260 dumpToLog()]: lastAppVersion: 7_74_0_972
2025/10/15 10:46:22:893  INF💛 [AppVersion.swift:261 dumpToLog()]: currentAppVersion: 7_74_0_972

The second one is from after the crash was resolved by linking the desktop app. These few lines basically always show up when I try and mark that previously crashing conversation as "Read"

2025/10/15 11:09:25:902  INF💛 [MessageSender:1204 performMessageSendAttempt]: Sending message: OWSReceiptsForSenderMessage; timestamp: 1760526565887; serviceId: <ACI:xxxx-xx-xx-xxx9fe>
2025/10/15 11:09:25:906  INF💛 [OWSChatConnection:391 makeRequest]: Sending… -> UD PUT v1/messages/xxxx-xx-xx-xxx9fe?story=false […866]
2025/10/15 11:09:26:053  INF💛 [OWSReceiptManager:644 markAsReadLocally]: Marking received messages and sent messages with reactions as read locally (in batches of 500)
2025/10/15 11:09:26:056  ERR❤️ [SDSDeserialization:27 required]: Missing required field: serverDeliveryTimestamp.
2025/10/15 11:09:26:057  ERR❤️ [OWSReceiptManager:662 markAsReadLocally]: unexpected failure fetching unread messages: SDSError: missingRequiredField(fieldName:_:_:_:): unspecified at SignalServiceKit/TSInteraction+SDS.swift#fromRecord(_:):1702
2025/10/15 11:09:26:096  INF💛 [MessageSender:362 sendMessage]: Sending OWSReadReceiptsForLinkedDevicesMessage, timestamp: 1760526566093
2025/10/15 11:09:26:103  INF💛 [MessageSender:1204 performMessageSendAttempt]: Sending message: OWSReadReceiptsForLinkedDevicesMessage; timestamp: 1760526566093; serviceId: <ACI:xxxx-xx-xx-xxxbe6>

In short the way I understand this is that those messages that used to crash the ios client are now preventing the whole marking as read process from going through, making it exit early for this conversation.

Now I'm not a Swift programmer but reading these lines and the associated code they refer to there seems to be no mechanism to gracefully handle message entries with missing data or are otherwise malformed in that code path.

I say this code path since there seems to be some more resilience in other areas since I can now use the conversation again, send and receive messages. Those malformed ones just don't show up, on any client. The only thing they interfere with is the process of marking messages as read.

Hope this was detailed enough and not too confusing. If anything is still unclear please don't hesitate to comment and ask.

Steps to reproduce

  • Dragging conversation to the right and selecting "Read", or any of the other methods to mark all as read etc.

Actual result: Unread count for conversation is not updated

Expected result: Invalid/Malformed messages simply get marked as read or better yet, cleaned up. They cannot even be seen in any client so they can just as well be erased from the db.

Device info

Device: iPhone 7

iOS version: 15.8.5

Signal version: 7.74

Link to debug log

Here are the 3 debug logs I generated when testing a few hypotheses myself.
Crash log was also sent at the time when the app was crashing but I have no reference myself to it at this point.
https://debuglogs.org/ios/7.80.0/bc771eaea9e25bcd5e58d0f35a2f8290aae88f26da8377a427c200a5bad34dc8.zip
https://debuglogs.org/ios/7.80.0/54e9923d2e9de575bed0e0d9d2ed73756e30fa61009da931f6bf71c4754cc857.zip
https://debuglogs.org/ios/7.80.0/a32bad58f6ecff4827a4fecfdfae75d5926e33ca0a1cc47f5eb462f893382533.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions