nextcloud / nextcloud/talk-ios
Conversation stays empty when initial history starts from an expired last-read message
- Dominant language
- Swift
- Stars
- 230
- Forks
- 121
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 38
Description
## Steps to reproduce
The failure and recovery sequence below was observed on a production instance.
1. Use a normal group conversation with message expiration enabled (one week in the affected conversation).
2. Have an existing participant read a message, then leave the conversation.
3. Allow that message and all preceding messages to expire while the participant's server-side last-read marker still refers to the removed message.
4. Post a newer message which has not expired.
5. Open the conversation in Talk iOS without a usable locally cached history around the old marker.
The user reported that setting up the app again did not resolve the issue, but the exact reset/reinstallation procedure was not recorded.
### Expected behaviour
The remaining messages should load even when the last-read marker points to a message that no longer exists. An empty backward-history response should not prevent retrieval of newer messages or put an otherwise connected conversation into offline mode.
### Actual behaviour
The conversation remained empty on the affected iPhone although a newer message existed on the server. Repeatedly reopening the conversation and restarting the app did not resolve it.
Read-only database inspection established:
- The affected user was an existing moderator in the conversation.
- The user's `oc_talk_attendees.last_read_message` was **54785**.
- Message **54785** no longer existed.
- The only remaining conversation message was **58434**, created on 2026-09-09 and expiring on 2026-09-16.
- The room was a normal group conversation (`type=2`, `threadId=0`), with message expiration set to 604800 seconds/7 days.
The exported client log records ten successful joins to the affected room between 20:27 and 20:38. Each has a same-second matching iOS backward-history request in the server access log, using the old marker and returning HTTP 304.
**I also got two very similiar reports for the Android Version of the app, but was not able to check exact version or client side logs yet. But maybe worth checking!**
### Observed workaround and recovery
The user opened the same conversation in a browser shortly before 20:42. Server inspection subsequently showed that the user's last-read marker had advanced to **58434**.
At 20:42:04, after another iOS app start, the initial history request used **58434** and returned **HTTP 200**. Forward polling then started, including a request with `timeout=30`.
This establishes recovery of the message-fetch sequence after updating the marker through the browser.
## Device information
**Device:** iPhone 13
**iOS version:** 26.6.1
**Talk version:** 24.0.4
## Server information
**Nextcloud version:** 34.0.3
**Talk version:** 24.0.4
**Custom Signaling server configured:** No
**Custom TURN server configured:** No
**Custom STUN server configured:** No
**Additional context:** The group is used for announcements with restricted default permissions; the affected user is a moderator, but acted only as client in the given example.
### Server log (data/nextcloud.log)
No matching chat-endpoint exception was found in the examined Nextcloud application log. The relevant HTTP responses appear in the Apache access log instead.
Client and Apache evidence, 2026-09-09
These are selected excerpts. Client timestamps align with server timestamps in CEST (UTC+02:00). The room token is replaced with `ROOM_TOKEN`; client thread labels, source IPs, HTTP protocol text and response sizes are omitted. No usernames, hostnames, credentials or message bodies are included.
```text
CLIENT 20:27:48.4940 Joining room ROOM_TOKEN for call false
CLIENT 20:27:48.6240 Joined room ROOM_TOKEN in NC successfully
SERVER 20:27:48
GET /ocs/v2.php/apps/spreed/api/v1/chat/ROOM_TOKEN?includeLastKnown=1&lastCommonReadId=-2&lastKnownMessageId=54785&limit=100&lookIntoFuture=0&markNotificationsAsRead=1&setReadMarker=1&threadId=0&timeout=0
HTTP 304
User-Agent: Mozilla/5.0 (iOS) Nextcloud-Talk v24.0.4
CLIENT 20:28:33.0440 Starting com.nextcloud.Talk, version 24.0.4, iOS 26.6.1, model iPhone
CLIENT 20:28:34.3300 Joining room ROOM_TOKEN for call false
CLIENT 20:28:34.6650 Joined room ROOM_TOKEN in NC successfully
SERVER 20:28:34
GET /ocs/v2.php/apps/spreed/api/v1/chat/ROOM_TOKEN?includeLastKnown=1&lastCommonReadId=-2&lastKnownMessageId=54785&limit=100&lookIntoFuture=0&markNotificationsAsRead=1&setReadMarker=1&threadId=0&timeout=0
HTTP 304
User-Agent: Mozilla/5.0 (iOS) Nextcloud-Talk v24.0.4
CLIENT 20:42:00.3440 Starting com.nextcloud.Talk, version 24.0.4, iOS 26.6.1, model iPhone
CLIENT 20:42:04.6890 Joining room ROOM_TOKEN for call false
CLIENT 20:42:04.8110 Joined room ROOM_TOKEN in NC successfully
SERVER 20:42:04
GET /ocs/v2.php/apps/spreed/api/v1/chat/ROOM_TOKEN?includeLastKnown=1&lastCommonReadId=-2&lastKnownMessageId=58434&limit=100&lookIntoFuture=0&markNotificationsAsRead=1&setReadMarker=1&threadId=0&timeout=0
HTTP 200
User-Agent: Mozilla/5.0 (iOS) Nextcloud-Talk v24.0.4
SERVER 20:42:04
GET /ocs/v2.php/apps/spreed/api/v1/chat/ROOM_TOKEN?includeLastKnown=0&lastCommonReadId=-2&lastKnownMessageId=58434&limit=100&lookIntoFuture=1&markNotificationsAsRead=1&setReadMarker=1&threadId=0&timeout=0
HTTP 304
User-Agent: Mozilla/5.0 (iOS) Nextcloud-Talk v24.0.4
SERVER 20:42:05
GET /ocs/v2.php/apps/spreed/api/v1/chat/ROOM_TOKEN?includeLastKnown=0&lastCommonReadId=-2&lastKnownMessageId=58434&limit=100&lookIntoFuture=1&markNotificationsAsRead=1&setReadMarker=1&threadId=0&timeout=30
HTTP 304
User-Agent: Mozilla/5.0 (iOS) Nextcloud-Talk v24.0.4
```
Contributor guide
Research direction
Start by reproducing the expired last-read marker sequence in Talk iOS and trace the initial backward-history request using the recorded lastKnownMessageId values and HTTP 304/200 responses. Inspect how an empty backward-history response affects loading and offline state; done means newer server messages appear even when the stored marker refers to an expired message.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100