Skip to content

GraphQL subscriptions can get stuck in connecting after repeated iOS background/foreground transitions #4220

Closed

Description

@akiramur

Describe the bug

Summary

We have a repro repo for an iOS GraphQL subscription reconnection issue after app lifecycle transitions.

With the current feature/multi-subscription-repro branch, we are now able to reproduce a stronger failure mode that is closer to our production app:

  • one or more subscriptions enter connecting
  • we have not observed them recover without fully terminating the app
  • the app does not recover by foregrounding again or by normal in-app actions

This stuck state is not reproducing on the simpler main branch of the repro repo. It is currently reproducing only on the multi-subscription variant.

We also observe a difference between build configurations:

  • the issue is harder to reproduce in Debug
  • the issue reproduces more easily in Release

Repro repository

  • Repo: https://github.com/akiramur/amplify-swift-ios-repros
  • Branch: feature/multi-subscription-repro
  • Commit: 6daca6d404771ab3cdac435976eacf0577958b40

Repro shape

This repro app uses:

  • Cognito auth with Hosted UI sign-in
  • AppSync GraphQL API
  • one GraphQL model
  • three concurrent onCreate subscription workers
  • background/foreground restart logic across all workers
  • in-app logging for worker connection state and lifecycle transitions

Environment

  • Amplify Swift: 2.58.1
  • Xcode: 26.3
  • iOS: 26.4.2
  • Device: iPhone 12
  • Repro backend: Amplify Gen 2 sandbox

Actual behavior

After repeating lock/unlock and app switching several times, one or more subscription workers eventually enter connecting and remain stuck there.

Once this happens:

  • one or more stuck subscription workers do not return to connected
  • normal app usage does not recover them
  • repeated foreground/background transitions do not recover them
  • the app remains in a degraded state until it is fully terminated and relaunched

In other words, after the stuck state is reached, a full app restart is the only reliable recovery we have observed.

Important observation

This behavior is currently reproducing only on the feature/multi-subscription-repro branch, which runs multiple concurrent subscription workers.

We are not reproducing the same stuck connecting state on the simpler main branch of the repro repo.

This multi-subscription branch appears closer to our production shape, where multiple subscriptions and lifecycle-driven restarts are active concurrently.

This suggests the issue may be related to one or more of:

  • multiple concurrent subscriptions
  • lifecycle-driven restart timing across multiple workers
  • reconnection races that do not appear with a single subscription

Steps To Reproduce

Steps to reproduce the behavior:

1. Start the backend sandbox and generate `amplify_outputs.json`.
2. Generate the Xcode project and run the app from the `feature/multi-subscription-repro` branch.
3. Sign in with Hosted UI.
4. Confirm all subscription workers reach `connected`.
5. Lock the device screen and leave the app idle for around 2 to 3 minutes.
6. Unlock the device.
7. Repeatedly switch between this app and other apps so the repro app cycles through background and foreground several times after unlocking.
8. Observe the aggregate connection badge, worker cards, and event log.

Expected behavior

Expected behavior

After app lock/unlock and repeated background/foreground transitions, all subscription workers should eventually reconnect and return to connected without requiring a full app restart.

Amplify Framework Version

2.58.1

Amplify Categories

API

Dependency manager

Swift PM

Swift version

5.9

CLI version

13.0.0

Xcode version

26.3 (17C529)

Relevant log output

<details>
<summary>Log Messages</summary>


INSERT LOG MESSAGES HERE

</details>

Is this a regression?

No

Regression additional context

No response

Platforms

No response

OS Version

26.4.2

Device

iPhone 12

Specific to simulators

No response

Additional context

No response

Activity

  1. jvh-aws commented on May 11, 2026

    @jvh-aws
    Contributor

    We are investigating the issue and will come back to you

  2. jvh-aws commented on May 11, 2026

    @jvh-aws
    Contributor

    Thanks for providing the sample app. However, I tried to reproduce the issue with the sample app that you provided, but couldn't reproduce it. Could you please share any further details that might be helpful?

    • More exact details on timing for causing the race condition
    • Any logs with Amplify.Logging.logLevel = .verbose, if that's feasible
    • Potentially, a screen recording if that's feasible
  3. thisisabhash commented on May 11, 2026

    @thisisabhash
    Member

    Hello,

    • Would you be able to test the version before this fix fix(api): recycle WebSocket and resubscribe on same-online network path change #4202 was released? Possibly 2.57.0 and before. This will help us in checking if this issue is a regression.
    • We have not been able to reproduce this issue in the provided sample app. So, a detailed verbose logs by enabling Amplify.Logging.logLevel = .verbose will be helpful.
    • I have created a possible fix in fix/gh-4220 branch. Please try it out and let us know if it resolves the issue.
  4. akiramur commented on May 16, 2026

    @akiramur
    Author

    Hi there,
    Thank you very much for checking.

    I reproduced this again using the latest code on branch feature/multi- subscription-repro (HEAD at the time of capture: 57afb04).

    One important detail is that this issue does not reliably reproduce while the
    debugger is attached. In my case, it reproduces much more consistently only
    after the debugger is detached, so I added app-side logging/export support in
    the repro app and collected the logs from there.

    Repro environment:

    • repro app built from the latest feature/multi-subscription-repro
    • Amplify.Logging.logLevel = .verbose enabled
    • aligned profile
    • foreground/background subscription recovery scenario

    What I collected:

    1. amplify-verbose-2026-05-16T06-26-41.672Z.log
    2. repro-report-2026-05-16T06-26-43.356Z.txt
    3. unified-log-2026-05-16T06-26-41.673Z.log

    What I’m seeing:

    • Auth.fetchSessionAPI continues to succeed
    • normal GraphQL query requests continue to succeed (query success items=8)
    • after foreground recovery, subscription workers restart but eventually all of
      them get stuck in connecting
    • the app-level watchdog then times out for every worker

    From the Amplify verbose log, the key failure pattern is:

    • AppSyncRealTimeClient Failed to send AppSync request start ...
    • NSPOSIXErrorDomain Code=53 "Software caused connection abort"
    • followed by AppSyncRealTimeSubscription ... Failed to subscribe, error: timeout
    • and then Subscription should be subscribed to be unsubscribed

    From the repro report:

    • final state is ConnectionState: connecting
    • all 6 workers end in state=connecting
    • queries still succeed while subscriptions fail to recover
    • the restart-required banner is triggered because subscriptions never return
      to connected

    From the unified log:

    • aligned foreground recovery starts as expected
    • some earlier attempts reconnect successfully
    • after the connection aborts, later attempts no longer recover and end in
      watchdog timeouts

    This looks consistent with the same failure family I am seeing in the
    production app: auth/session fetch and queries still work, but AppSync realtime
    subscription recovery gets stuck after foreground/background transitions.

    Because debugger-attached runs tend not to reproduce, I collected these logs
    directly from the app using the built-in export flow:

    1. reproduce the issue without the debugger attached
    2. open the app
    3. open the Log Export section
    4. tap Refresh Exports
    5. export:
      • Verbose Log
      • Unified Log
      • Repro Report

    I am attaching those 3 redacted files here.

    amplify-verbose-2026-05-16T06-26-41.672Z.log

    repro-report-2026-05-16T06-26-43.356Z.txt

    unified-log-2026-05-16T06-26-41.673Z.log

  5. akiramur commented on May 16, 2026

    @akiramur
    Author

    I also tested the proposed fix branch fix/gh-4220, but I was still able to
    reproduce the same failure pattern.

    The logs still show:

    • Failed to send AppSync request start(...)
    • NSPOSIXErrorDomain Code=53 "Software caused connection abort"
    • Failed to subscribe, error: timeout
    • Subscription should be subscribed to be unsubscribed

    The app-side unified log still shows aligned foreground recovery followed by
    watchdog timeouts across subscription workers.

    So in my environment, the proposed fix branch does not appear to resolve this
    issue.

  6. thisisabhash commented on May 20, 2026

    @thisisabhash
    Member

    Thank you for posting logs and reproduction app and testing out the fix branch.

    • I have not been able to reproduce the issue with the provided sample app. Are there any special conditions like
      • network
      • iOS version
      • real device or simulator
        in which you are able to reproduce the issue?
    • Based on the logs provided, I have updated the branch with additional fixes - fix/gh-4220. Please try it out and let us know if it resolves the issue.
  7. akiramur commented on May 20, 2026

    @akiramur
    Author

    @thisisabhash thank you for the new fix. unfortunately it did not improve the symptom even with the new fix.

    Here is the info how I reproduce the issue.

    • network: Wifi only or wifi and cellar
    • iOS version: 26.4.2
    • real device or simulator: real device(iPhone 12, iPhone 16e)

    I felt it was harder to produce this on iPad. I could not reproduce the issue when the debugger is attached.

    Step to reproduce

    1. Launch the app and wait until the subscriptions are connected.
    2. Swipe up slightly from the bottom edge so the app briefly enters the inactive state, then return to the app immediately.
    3. This triggers foreground recovery and the subscriptions start reconnecting. You may see them enter connecting....
    4. While the app is reconnecting, swipe up further and send the app to the background.
    5. Return to the app within a few seconds.
    6. Repeat steps 2 through 5 several times.
    7. Eventually, the subscriptions stop recovering correctly and remain stuck in connecting..., or the app shows a message telling you to fully close and reopen it.
  8. 2 remaining items

  9. akiramur commented on May 21, 2026

    @akiramur
    Author

    I tested again with the latest fix/gh-4220 branch and can confirm the issue
    still reproduces.

    The app log shows it is running with:

    fe96a4a

    At first, the WebSocket connection succeeds normally and subscriptions receive
    connection_ack and start_ack. After that, the WebSocket hits:

    NSPOSIXErrorDomain Code=53 "Software caused connection abort"

    Once that happens, unsubscribe requests start failing, and all subsequent
    subscription start requests fail with the same error and eventually time out.
    In other words, the connection does not recover and the subscriptions remain
    stuck in the failed reconnect loop.

    I attached a redacted verbose log that shows this sequence.

    Reproduction pattern:

    1. Launch the app and wait until subscriptions are connected.
    2. Swipe up slightly so the app briefly enters inactive, then immediately
      return to it.
    3. While it is reconnecting, swipe up further to send it to the background.
    4. Return to the app.
    5. Repeat this several times.

    After a few cycles, subscription recovery fails and the app gets stuck in the
    same broken state as before.

    fix4-amplify-verbose-redacted.log

  10. thisisabhash commented on May 21, 2026

    @thisisabhash
    Member

    Thank you for the new logs. I have updated the branch fix/gh-4220 with new updates (23d5a38).
    Please try it out and post verbose logs if the issue persists.

  11. akiramur commented on May 24, 2026

    @akiramur
    Author

    Thank you for the fix.
    The symptom has improved significantly compared with what we were seeing
    before, so this is not the same severity as the earlier production issue.
    However, we observed behavior in the environment of our production iOS
    app that still looks concerning, and we would like your help reviewing whether
    this is expected AppSync realtime client behavior.

    We are seeing repeated AppSync realtime disconnect/reconnect cycles on iOS.
    This does not look like a simple “subscription never reconnects” failure. In
    the attached verbose log, the SDK does reconnect at the websocket level and
    resumes subscriptions, but the connection appears operationally unstable and
    can repeatedly disconnect again within seconds.

    Observed Behavior

    From the attached log:

    • websocket disconnects with connectionLost / disconnected
    • the SDK logs reconnecting appSyncClient after connection drop
    • the websocket reconnects and receives connection_ack
    • the SDK logs Resuming existing subscriptions
    • individual subscriptions receive start_ack and transition back to Subscribed
    • shortly after that, the websocket may disconnect again and repeat the same
      cycle

    Representative patterns from the log:

    • repeated NSPOSIXErrorDomain Code=53 "Software caused connection abort"
    • repeated NSPOSIXErrorDomain Code=57 "Socket is not connected"
    • repeated connection_ack
    • repeated start_ack / Subscribed after reconnect

    Why We Think This Is an SDK/AppSync Realtime Issue

    Our app is not relying on its own automatic reconnect loop for this behavior.
    What the log shows is the AppSync realtime client internally reconnecting and
    resuming subscriptions on its own.

    So the issue is not simply “our app forgot to recreate subscriptions.”
    The issue appears to be that the AppSync realtime layer enters repeated
    disconnect/reconnect/resubscribe cycles, even though auth remains valid and
    reconnect technically succeeds.

    amplify-verbose-20260524-144520.redacted.txt

  12. akiramur commented on May 27, 2026

    @akiramur
    Author

    We continued testing and found another concerning behavior.

    Once this condition starts occurring, the app tends to return to disconnected
    again very quickly even after the SDK reconnects and resumes subscriptions. In
    practice, it does not seem to recover cleanly on its own, and the connection
    remains unstable until the app is fully restarted.

    So although the symptom is improved compared with the earlier issue, we are
    still seeing a failure mode where reconnect and resubscribe technically
    succeed, but the realtime connection soon becomes disconnected again and keeps
    repeating that pattern unless the app is restarted.

  13. jvh-aws commented on May 27, 2026

    @jvh-aws
    Contributor

    Thanks a lot for the additional input! We're continuing to investigate. Did you by any chance test if this also occurs with an older version, e.g. v2.56.0?

  14. akiramur commented on Jun 3, 2026

    @akiramur
    Author

    @jvh-aws v2.56.0 looks good. So far I haven't been able to reproduce the issue so far since the last week.

  15. harsh62 commented on Jun 29, 2026

    @harsh62
    Contributor

    Closing in favor of #4229

  16. github-actions commented on Jun 29, 2026

    @github-actions
    Contributor

    This issue is now closed. Comments on closed issues are hard for our team to see.
    If you need more assistance, please open a new issue that references this one.
    If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions