Skip to content

"cloud_firestore EventChannel callbacks fire from wrong thread, engine fast-fails." The fix pattern is the same opt-in flag approach, applied to Firestore's channels. #18226

@alancook

Description

@alancook

[cloud_firestore] Windows: FAST_FAIL_INVALID_ARG (0xc0000409) from EventChannel callback on wrong thread (same root cause as #18210 / closed PR #18223)

Paste this into a new issue at: https://github.com/firebase/flutterfire/issues/new/choose
Pick Bug report.


Bug description

This is the cloud_firestore manifestation of the same Windows plugin
threading bug already reported for firebase_auth. The Windows
firebase_firestore_plugin dispatches EventChannel traffic (snapshot
listeners, metadata streams) from a native background thread. The Flutter
Windows engine requires platform channel traffic on the platform thread and
calls fml::KillProcess__fastfail(FAST_FAIL_INVALID_ARG) when that
contract is violated, terminating the host process with 0xc0000409
(STATUS_STACK_BUFFER_OVERRUN, subcode 0x5).

Related work:

PR #18223 only covers the firebase_auth id-token EventChannel. After
applying that workaround conceptually (skipping the auth id-token channel),
cloud_firestore still crashes because Firestore opens its own
EventChannels (snapshot subscriptions, query metadata) that exhibit the same
wrong-thread dispatch. This issue requests the equivalent treatment for
cloud_firestore.

Steps to reproduce

  1. flutter create an app, target Windows desktop.
  2. Add firebase_core, firebase_auth, cloud_firestore (versions in env block).
  3. Configure firebase_options.dart. (No first-class Windows FirebaseOptions
    exists for our project; on Windows we pass the Web app options to
    Firebase.initializeApp(...). This is the documented Windows pattern today.)
  4. Sign in:
    await FirebaseAuth.instance.signInWithEmailAndPassword(...);
  5. Touch any Firestore API:
    await FirebaseFirestore.instance.collection('test').limit(1).get();
  6. Process is terminated immediately with 0xc0000409.

A minimal example:

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'firebase_options.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.web, // Web options used on Windows
  );

  await FirebaseAuth.instance.signInWithEmailAndPassword(
    email: 'test@example.com',
    password: '...',
  );

  // Crashes here on Windows desktop with 0xc0000409.
  final snap = await FirebaseFirestore.instance
      .collection('test')
      .limit(1)
      .get();
  debugPrint('docs: ${snap.size}');

  runApp(const MaterialApp(home: Scaffold(body: Center(child: Text('ok')))));
}

Expected behavior

The Firestore call returns normally or throws a catchable
FirebaseException. The host process must not be terminated by an unhandled
fast-fail.

Actual behavior

Exception code: 0xc0000409 (STATUS_STACK_BUFFER_OVERRUN)
Subcode:        0x5 (FAST_FAIL_INVALID_ARG)
Faulting IP:    patient_manager+0xbe15  ->  cd 29   int 29h

WinDbg !analyze -v (relevant frames, with the same shape as the engine
fml::KillProcessPlatformMessageHandlerStandard::InvokeHandler
IncomingMessageDispatcher::HandleMessage → plugin-callback-from-wrong-thread
pattern documented in PR #18223):

STACK_TEXT:
patient_manager+0xbe15
patient_manager+0xbe63
patient_manager+0x1723f
patient_manager!CloudFirestorePluginCApiRegisterWithRegistrar+0x203c3
patient_manager!CloudFirestorePluginCApiRegisterWithRegistrar+0x2107e
patient_manager+0x1374f
patient_manager!CloudFirestorePluginCApiRegisterWithRegistrar+0x29125
patient_manager!CloudFirestorePluginCApiRegisterWithRegistrar+0x2114f
patient_manager+0x161d7
patient_manager!CloudFirestorePluginCApiRegisterWithRegistrar+0x1f0d1
patient_manager+0x11801
flutter_windows!InternalFlutterGpu_Texture_AsImage+0x15fd66
flutter_windows!FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable+0x2a49
flutter_windows!InternalFlutterWindows_WindowManager_GetFullscreen+0x9abfa
... (Win32 message dispatch)
user32!UserCallWinProcCheckWow+0x356
user32!DispatchMessageWorker+0x1dd
patient_manager+0xcb16
patient_manager!FirebaseStoragePluginCApiRegisterWithRegistrar+0x95810a
kernel32!BaseThreadInitThunk+0x17
ntdll!RtlUserThreadStart+0x2c

FAILURE_BUCKET_ID: FAIL_FAST_INVALID_ARG_c0000409_patient_manager.exe!Unknown

Notes:

What we already tried (Dart-side mitigations that do NOT help)

  • Calling Firestore only after auth completes ✕
  • Calling Firestore before auth ✕
  • Settings(persistenceEnabled: false), host: overrides ✕
  • disableNetwork() before any read ✕
  • Different read APIs (get, snapshots(), doc().get()) ✕
  • Different Firestore databases / projects ✕
  • Wrapping calls in Future.microtask, addPostFrameCallback,
    Future.delayed, runZonedGuarded, custom BinaryMessenger
    (consistent with PR fix(auth, windows): add opt-in flag to skip id-token EventChannel (FAST_FAIL_INVALID_ARG workaround) #18223's analysis: every Dart-side mitigation runs
    after the native side has already dispatched from the wrong thread)

The only mitigation that prevents the crash in our app is removing every
cloud_firestore call from the Windows code path
. We replaced custom-claims
hydration with direct base64url decode of user.getIdToken(false) and
short-circuited every Firestore read/write on Platform.isWindows. With
cloud_firestore not invoked at all, the app is stable.

Proposed fix (mirroring PR #18223 for Firestore)

Add an opt-in static flag on FirebaseFirestorePlatform (or an analogous
location) to skip the Windows snapshot/metadata EventChannel registration
the same way PR #18223 proposed for firebase_auth.id-token. Apps that don't
need live snapshots() streams on Windows could opt in and use imperative
get() calls only. Long-term fix is still
flutter/flutter#134346,
but an explicit Dart-only escape hatch unblocks every Windows user today.

Environment

flutter --version
Flutter 3.38.7  •  channel stable
Framework • revision 6f3039bf7c (2026-01-13)
Engine    • revision 78fc3012e4
Tools     • Dart 3.10.7 • DevTools 2.51.1

flutter doctor -v Windows toolchain:

  • Visual Studio Community 2026, version 18.5.11716.220
  • Windows 10 SDK 10.0.26100.0
  • Windows 11 25H2, Build 10.0.26200.8246, x64

Plugin versions (pubspec.lock):

Plugin Version sha256
cloud_firestore 6.3.0 3ac242332166ae5037bd87bc343744bb96d88d7b13f791492b00958ce5cc6c63
cloud_firestore_platform_interface 7.2.0 1bd08b736e1015e8bf5448f5ef67b2087a2380c2c1c7972f8403c1c7b41f5359
firebase_core 4.7.0 d5a94b884dcb1e6d3430298e94bfe002238094cdfd5e29202d536ee2120f9158
firebase_auth 6.4.0 b12cb1e2e87797d27e0041100b73ebf890dbafcff2e7e991d4593f5e8e309808
firebase_storage 13.3.0 825a5a64addc66b57a2e793b5e40343d1364e8b5a2a0d7e6cfc116ae9c021fbd
cloud_functions 6.2.0 036aa4f3b880935bda48fd6ab516e0f11686c328a46313226b9cbad9220b4c59
firebase_messaging 16.2.0 e5c93e8e7a9b0513f94bb684d2cf100e32e7dcdf2949574386b1955fc9a9b96a

Build mode: debug and release both crash identically.

Crash artifacts

  • Full minidump: ~390 MB — happy to share via private channel if requested.
  • Sanitized WinDbg !analyze -v output: included above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs AttentionThis issue needs maintainer attention.platform: windowsIssues / PRs which are specifically for Windows.plugin: authtype: bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions