signalapp / signalapp/Signal-Android

Rate limit when communicating with one particular person

Open
#14,775 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

wontfix
Dominant language
Kotlin
Stars
29.4k
Forks
6.9k
PR merge metrics
No merged PRs in 30d

Description

Guidelines
  • 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

When communicating with one particular friend, I would some time hit rate limit and cannot send message (spinning dot do not turn into one check mark)

  • This doesn't happen with any other person
  • This does happen within group, but message to other people would deliver fine except said person.
  • While I am waiting to send my message to said person, said person can send me message and I would recieve them just fine
  • While I am waiting to send my message to said person, I can send and recieve messages from other people and group chat just fine.
  • Deleting unsend message to said person does not resolve the rate limit
  • This issue usually go away over night, and would randomly reoccur every couple of weeks.
Screenshots

No response

Device

Pixel 7a

Android version

16 (Graphene OS without Google Play)

Signal version

8.9.1

Link to debug log

https://debuglogs.org/android/8.9.1/d0dd8e74e5f027868a90e3c118fc577fa790a069bf3c9d0996b3df0feb0303fe

[8.9.1] [49   ] 2026-05-13 22:26:08.647 EDT D SignalServiceMessageSender: [1778725568646] Sending a typing message to 1 recipient(s) using 1:1 messages.
[8.9.1] [49   ] 2026-05-13 22:26:08.647 EDT D SignalServiceMessageSender: [1778725568646] Sending to 1 recipients.
[8.9.1] [18556] 2026-05-13 22:26:08.706 EDT D LibSignalChatConnection: [libsignal-unauth:38049743] [sendRequest] Success: 409
[8.9.1] [694  ] 2026-05-13 22:26:08.709 EDT W SignalServiceMessageSender: [sendMessage][1778725568646] Handling mismatched devices. (StatusCode: 409)
[8.9.1] [694  ] 2026-05-13 22:26:08.709 EDT W SignalServiceMessageSender: [handleMismatchedDevices] Address: ********-****-****-****-*********8db, ExtraDevices: [], MissingDevices: [2]
[8.9.1] [694  ] 2026-05-13 22:26:08.711 EDT D KeysApi: Fetching prekeys for ********-****-****-****-*********8db.2, i.e. GET /v2/keys/********-****-****-****-*********8db/2
[8.9.1] [18557] 2026-05-13 22:26:08.737 EDT D LibSignalChatConnection: [libsignal-auth:604455] [sendRequest] Success: 429
[8.9.1] [694  ] 2026-05-13 22:26:08.738 EDT W SignalServiceMessageSender: [1778725568646] Hit rate limit: ********-****-****-****-*********8db
org.whispersystems.signalservice.api.push.exceptions.RateLimitException: [429] Rate limit exceeded: 429
	at org.whispersystems.signalservice.api.NetworkResultUtil.toPreKeysLegacy(NetworkResultUtil.kt:125)
	at org.whispersystems.signalservice.api.SignalServiceMessageSender.handleMismatchedDevices(SignalServiceMessageSender.java:3024)
	at org.whispersystems.signalservice.api.SignalServiceMessageSender.lambda$sendMessageRx$17(SignalServiceMessageSender.java:2378)
	at org.whispersystems.signalservice.api.SignalServiceMessageSender.$r8$lambda$SYPQNQkQYueQagvZ5NsSwnmMvkI(SignalServiceMessageSender.java:0)
	at org.whispersystems.signalservice.api.SignalServiceMessageSender$$ExternalSyntheticLambda29.call(R8$$SyntheticClass:0)
	at io.reactivex.rxjava3.internal.operators.single.SingleFromCallable.subscribeActual(SingleFromCallable.java:43)
	at io.reactivex.rxjava3.core.Single.subscribe(Single.java:4813)
	at io.reactivex.rxjava3.internal.operators.single.SingleFlatMap.subscribeActual(SingleFlatMap.java:37)
	at io.reactivex.rxjava3.core.Single.subscribe(Single.java:4813)
	at io.reactivex.rxjava3.internal.operators.single.SingleResumeNext$ResumeMainSingleObserver.onError(SingleResumeNext.java:80)
	at io.reactivex.rxjava3.internal.operators.single.SingleFlatMap$SingleFlatMapCallback$FlatMapSingleObserver.onError(SingleFlatMap.java:117)
	at io.reactivex.rxjava3.internal.disposables.EmptyDisposable.error(EmptyDisposable.java:78)
	at io.reactivex.rxjava3.internal.operators.single.SingleError.subscribeActual(SingleError.java:41)
	at io.reactivex.rxjava3.core.Single.subscribe(Single.java:4813)
	at io.reactivex.rxjava3.internal.operators.single.SingleFlatMap$SingleFlatMapCallback.onSuccess(SingleFlatMap.java:85)
	at io.reactivex.rxjava3.internal.operators.single.SingleObserveOn$ObserveOnSingleObserver.run(SingleObserveOn.java:81)
	at io.reactivex.rxjava3.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
	at io.reactivex.rxjava3.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:25)
	at java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1154)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:652)
	at java.lang.Thread.run(Thread.java:1563)
	at org.signal.core.util.concurrent.SignalExecutors$NumberedThreadFactory$1.run(SignalExecutors.java:100)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the debug log and trace the reported path through SignalServiceMessageSender.java, especially handleMismatchedDevices, then inspect NetworkResultUtil.kt and KeysApi around the prekey request. Compare the 409 mismatched-device response with the subsequent 429 rate limit. Done means the recipient-specific send failure is explained and verified against the reported behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin
Domain
mobile, networking
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.