[REQUIRED] Environment info
firebase-tools: reproduced on both 14.8.0 and 15.25.1
Platform: Windows 11 Pro (10.0.26200), Node v24.16.0
Emulators running: auth, firestore, functions (started with firebase emulators:start --only auth,firestore,functions)
[REQUIRED] Test case
The Auth emulator stops serving requests partway through a long Playwright run and never recovers.
The trigger needs browser traffic against the emulator, so I have not managed to reduce it to a script. What I can give is a precise characterisation and several experiments that narrow it down considerably.
Setup: an Angular app under test, with Playwright routing every identitytoolkit.googleapis.com and securetoken.googleapis.com request into the Auth emulator via page.route(...) / route.fetch(...). Roughly 120 tests run serially with one worker, and each beforeEach clears both emulators (DELETE /emulator/v1/projects/{project}/accounts and the equivalent Firestore endpoint).
[REQUIRED] Steps to reproduce
- Start the emulators as above.
- Run a serial suite where each test signs in / creates accounts through the emulator via a browser, and clears accounts between tests.
- Watch the duration of each account-clear call.
[REQUIRED] Expected behavior
The Auth emulator keeps answering for the life of the run.
[REQUIRED] Actual behavior
After a fixed number of clears, the Auth emulator stops responding to every request and never recovers for the remainder of the process. The Firestore emulator, in the same process, is unaffected throughout.
Timings for the account-clear call across one run on 15.25.1 (calls 1–62 elided, all in this range):
call 1: 7ms
call 20: 3ms
call 40: 4ms
call 62: 7ms
call 63: 15007ms <- bound I imposed; without it, it never returns
call 64: 15003ms
call 65: 15015ms
... (every subsequent call, to the end of the run)
Every test after that point fails in beforeEach.
The wedge point is deterministic. Call 63 on 15.25.1, reproduced identically across three separate runs. Calls 28–29 on 14.8.0. So the upgrade moves the threshold but does not remove it.
What I have ruled out
It is not the client. I first used fetch against the REST endpoint, then switched to the Admin SDK (listUsers + deleteUsers), a completely different HTTP path. Both wedge at the same point in the run. The Admin SDK has no timeout of its own, so it simply never settles.
It is not connection-scoped. During a run I polled GET /emulator/v1/projects/{project}/config every 5 seconds from a separate process, with a fresh connection each time — read-only, no mutation. It returned 200 in ~230ms throughout, and then at the exact moment the suite's clears began hanging it started timing out at 20s and never recovered:
14:47:27 probe 200 0.236472
14:47:52 probe 000 20.015710
14:48:17 probe 000 20.003287
14:48:42 probe 000 20.003797
... (never recovers)
An unrelated process, on a new socket, doing a read-only GET, is refused. That points at the emulator's request handling rather than anything on the client side.
It is not call volume alone. Against a freshly started emulator with no browser and no app involved, this ran clean:
// 200 cycles: create two accounts, list all, delete all
for (let i = 1; i <= 200; i++) {
await auth.createUser({ email: `probe${i}a@test.com`, password: 'password123' });
await auth.createUser({ email: `probe${i}b@test.com`, password: 'password123' });
const uids = [];
let token;
do {
const page = await auth.listUsers(1000, token);
uids.push(...page.users.map(u => u.uid));
token = page.pageToken;
} while (token);
if (uids.length) await auth.deleteUsers(uids);
}
// 200/200 cycles, 4–7ms each, no wedge
So the trigger involves the browser-side traffic, not the clearing itself. My guess, unverified, is that requests proxied in from the browser and abandoned when a page closes leave something in a state the emulator does not recover from, and that the threshold is a connection or handle limit rather than a count of operations.
Impact and workaround
While it lasts, the emulator makes an otherwise healthy suite report 10–14 failures per run, all of them bare timeout in beforeEach on tests that have nothing wrong with them. It is very easy to misread as flaky tests.
The workaround is to shard the suite into separate playwright test invocations so each gets a fresh emulator and no single run approaches the threshold. With that, the same suite passes 122/122.
Happy to run further diagnostics if there is a debug flag or log that would help pin down what is holding the emulator open.
[REQUIRED] Environment info
firebase-tools: reproduced on both
14.8.0and15.25.1Platform: Windows 11 Pro (10.0.26200), Node v24.16.0
Emulators running:
auth,firestore,functions(started withfirebase emulators:start --only auth,firestore,functions)[REQUIRED] Test case
The Auth emulator stops serving requests partway through a long Playwright run and never recovers.
The trigger needs browser traffic against the emulator, so I have not managed to reduce it to a script. What I can give is a precise characterisation and several experiments that narrow it down considerably.
Setup: an Angular app under test, with Playwright routing every
identitytoolkit.googleapis.comandsecuretoken.googleapis.comrequest into the Auth emulator viapage.route(...)/route.fetch(...). Roughly 120 tests run serially with one worker, and eachbeforeEachclears both emulators (DELETE /emulator/v1/projects/{project}/accountsand the equivalent Firestore endpoint).[REQUIRED] Steps to reproduce
[REQUIRED] Expected behavior
The Auth emulator keeps answering for the life of the run.
[REQUIRED] Actual behavior
After a fixed number of clears, the Auth emulator stops responding to every request and never recovers for the remainder of the process. The Firestore emulator, in the same process, is unaffected throughout.
Timings for the account-clear call across one run on
15.25.1(calls 1–62 elided, all in this range):Every test after that point fails in
beforeEach.The wedge point is deterministic. Call 63 on
15.25.1, reproduced identically across three separate runs. Calls 28–29 on14.8.0. So the upgrade moves the threshold but does not remove it.What I have ruled out
It is not the client. I first used
fetchagainst the REST endpoint, then switched to the Admin SDK (listUsers+deleteUsers), a completely different HTTP path. Both wedge at the same point in the run. The Admin SDK has no timeout of its own, so it simply never settles.It is not connection-scoped. During a run I polled
GET /emulator/v1/projects/{project}/configevery 5 seconds from a separate process, with a fresh connection each time — read-only, no mutation. It returned 200 in ~230ms throughout, and then at the exact moment the suite's clears began hanging it started timing out at 20s and never recovered:An unrelated process, on a new socket, doing a read-only GET, is refused. That points at the emulator's request handling rather than anything on the client side.
It is not call volume alone. Against a freshly started emulator with no browser and no app involved, this ran clean:
So the trigger involves the browser-side traffic, not the clearing itself. My guess, unverified, is that requests proxied in from the browser and abandoned when a page closes leave something in a state the emulator does not recover from, and that the threshold is a connection or handle limit rather than a count of operations.
Impact and workaround
While it lasts, the emulator makes an otherwise healthy suite report 10–14 failures per run, all of them bare
timeout in beforeEachon tests that have nothing wrong with them. It is very easy to misread as flaky tests.The workaround is to shard the suite into separate
playwright testinvocations so each gets a fresh emulator and no single run approaches the threshold. With that, the same suite passes 122/122.Happy to run further diagnostics if there is a debug flag or log that would help pin down what is holding the emulator open.