Repository navigation
Description
Describe the bug
Our TestFlight release build intermittently crashes during app startup while AWSCloudWatchLoggingPlugin is responding to an authentication identity change.
The crash occurs in the Swift concurrency runtime while switching to a LogActor executor. At the same time, other threads are resetting the previous CloudWatch logging session and creating its replacement.
This appears to be a data race involving the mutable session property in AWSCloudWatchLoggingSessionController. The controller is declared @unchecked Sendable, but access to session is not synchronized.
When the user identifier changes, userIdentifierDidChange() starts an unstructured reset task and then immediately replaces the session:
private func userIdentifierDidChange() {
resetCurrentLogs()
updateSession()
updateConsumer()
connectProducerAndConsumer()
}
private func resetCurrentLogs() {
Task {
do {
try await session?.logger.resetLogs()
} catch {
Amplify.Logging.error("Error resetting logs with \(error)")
}
}
}
The asynchronous task can read session while updateSession() replaces it. This may allow the task to access a stale logger or LogActor, resulting in a pointer-authentication trap when the Swift runtime attempts to acquire the actor executor.
Frequency: Intermittent, but recurring — observed 3 times for the same TestFlight user within a short time.
Crashlogs Attached:
testflight_feedback-26-scrubbed.zip
testflight_feedback-25-scrubbed.zip
testflight_feedback-24-scrubbed.zip
Steps To Reproduce
Steps to reproduce the behavior:
* Configure Amplify with AWSCognitoAuthPlugin and AWSCloudWatchLoggingPlugin.
* Enable CloudWatch logging and generate log messages during application startup.
* Install and launch an optimized release build through TestFlight on a device with an existing or recoverable authenticated session.
* Allow Cognito to publish its configured or signed-in authentication event.
* AWSCloudWatchLoggingPlugin transitions from the guest or previous logging session to the authenticated user session.
* Intermittently, the app crashes while the old session is being reset and the replacement session is being initialized.
Not yet reproducible on demand. The recurrence for a single user suggests a persistent app state, workload, or environment-specific trigger rather than an isolated transient failure.Expected behavior
CloudWatch logging should safely transition between guest and authenticated-user sessions without crashing, including in optimized release and TestFlight builds.
Resetting the previous session and constructing the replacement session should be serialized, and asynchronous cleanup should retain a stable reference to the session being cleaned up.
Amplify Framework Version
2.62.0
Amplify Categories
Auth
Dependency manager
Swift PM
Swift version
Swift 5 language mode, compiled with Swift 6.2.1 toolchain
CLI version
N/A - Amplify CLI is not used to cnofigure this application
Xcode version
26.1.1
Relevant log output
<details>
<summary>Log Messages</summary>
App version: 3.2.1 (2965.0.1)
Distribution: TestFlight
Device: iPhone15,5
OS: iOS 26.6 (23G71)
Architecture: arm64e
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x0000000183213a78
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Triggered by Thread: 6
Thread 6 Crashed:
0 libswift_Concurrency.dylib swift_distributed_actor_is_remote + 36
1 libswift_Concurrency.dylib DefaultActorImpl::tryLock(bool) + 96
2 libswift_Concurrency.dylib tryAssumeThreadForSwitch + 24
3 libswift_Concurrency.dylib swift_task_switchImpl + 436
ARM exception state:
esr: 0xf200c472 (Breakpoint) pointer authentication trap DA
A concurrent thread was constructing a replacement logging session:
LogRotation.createLogFile(in:index:fileSizeLimitInBytes:)
LogRotation.selectNextLogFile(from:fileCountLimit:fileSizeLimitInBytes:)
LogRotation.init(directory:fileSizeLimitInBytes:)
LogActor.init(directory:fileSizeLimitInBytes:)
RotatingLogger.init(directory:category:namespace:logLevel:fileSizeLimitInBytes:)
AWSCloudWatchLoggingSession.init(...)
AWSCloudWatchLoggingSessionController.updateSession()
Another concurrent thread was resetting the previous session:
LogRotation.createLogFile(in:index:fileSizeLimitInBytes:)
LogRotation.reset()
LogActor.deleteLogs()
RotatingLogger.resetLogs()
AWSCloudWatchLoggingSessionController.resetCurrentLogs()
</details>Is this a regression?
No
Regression additional context
A specific version-to-version regression has not been confirmed because we do not have a known-good version for this exact stack signature.
However, this resembles a recurrence through a different concurrency path of the release-only CloudWatch logging crashes reported in #3970, #3987, and #4001. Those issues were closed after fixes released before 2.62.0. This report occurs on 2.62.0 and has a different actor-executor crash signature.
Platforms
iOS
OS Version
iOS 26.6 (23G71)
Device
iPhone 15 Plus (iPhone 15,5), arm64e
Specific to simulators
No
Additional context
The crash happened automatically during application startup without user interaction. The crash report’s launch and failure timestamps are approximately 300 milliseconds apart, which is consistent with authentication restoration and CloudWatch session initialization.
Relevant implementation details:
- AWSCloudWatchLoggingSessionController is @unchecked Sendable.
- Its mutable session, consumer, subscriptions, and user identifier are not protected by actor isolation or a controller-level lock.
- resetCurrentLogs() launches an unstructured task that reads self.session.
- userIdentifierDidChange() immediately calls updateSession(), which replaces that property.
- The crash report simultaneously shows one thread resetting logs and another constructing a new LogActor.
A possible fix is to serialize controller state transitions and strongly capture the old session or logger before launching asynchronous cleanup. The cleanup task should not read the controller’s mutable session property after it has been scheduled.
As an application-level diagnostic workaround, completely omitting AWSCloudWatchLoggingPlugin prevents this path. Merely setting its configuration to "enable": false may not be sufficient because the installed plugin continues observing authentication events.
Crashlogs Attached:
testflight_feedback-26-scrubbed.zip
testflight_feedback-25-scrubbed.zip
testflight_feedback-24-scrubbed.zip
Activity
thisisabhash commentedon Oct 13, 2026
Hi @mattweight, thanks for the detailed report. Your analysis is right: the controller didn't synchronize its state, so the reset task and log calls could read
sessionwhile it was being replaced and use a freed session.A fix is in review in #4395. It guards the controller's state with a lock and, as you suggested, captures the outgoing session's logger before the swap. It also fixes a related race in
RotatingLogger, and a disabled plugin no longer restarts on the next auth event.You're welcome to try the fix before it's released: point your amplify-swift package dependency at the
fix/logging-session-controller-racebranch, and let us know how it goes. We'll update this issue when the fix is released.github-actions commentedon Oct 14, 2026
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.
mattweight commentedon Oct 22, 2026
@thisisabhash - any idea when this will show up in a new release? Can we get one sooner than later? Thanks!
thisisabhash commentedon Oct 26, 2026
@mattweight This is released in https://github.com/aws-amplify/amplify-swift/releases/tag/2.63.0 .
fix(logging): synchronize CloudWatch logging session swaps and log st…