nextcloud / nextcloud/talk-ios

Conversation stays empty when initial history starts from an expired last-read message

Open
#2,702 0 comments 0 reactions 0 assignees View on GitHub
0. Needs triage bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.