Repository navigation
Edge 152 crashes with 0xC0000005 in msedge.dll during a CDP download over --remote-debugging-pipe after profile reuse #461
Description
Summary
Microsoft Edge Stable 152.0.4191.53 can terminate with a native read-access violation during a CDP-controlled download after the same user-data directory is reused across browser launches.
The failure reproduces with a dependency-free Node.js harness that sends CDP messages directly; Playwright is not imported or executed. With the Edge binary, profile lifecycle, page, 5 MiB payload, download behavior, and CDP command sequence held constant, changing only the transport from --remote-debugging-pipe to --remote-debugging-port avoids the crash in the observed environment.
By default, the harness creates a dedicated new profile and serves the page and payload from a loopback HTTP server. It does not use an existing browser profile, extensions, authentication state, or an external website.
Environment
- Windows 11 Home x64, 10.0.26200 (build 26200)
- Microsoft Edge Stable 152.0.4191.53, x64
- Node.js 24.18.1 (the harness requires Node.js 22 or later)
- Initially observed through Playwright for Python 1.62.0, but Playwright is not required to reproduce
- Regression range: not established; the minimized matrix was validated against Edge Stable 152
Minimal reproduction
git clone https://github.com/ryo-whaletech/microsoft-edge-cdp-pipe-download-crash-repro.git
cd microsoft-edge-cdp-pipe-download-crash-repro
node repro.mjs --transport pipe --iterations 5 --download-behavior allowOn the affected system, the first launch normally succeeds and the second or third launch exits with 3221225477 (0xC0000005) before the download is finalized.
Transport control:
node repro.mjs --transport port --iterations 8 --download-behavior allowThe port control completed 8/8 profile reuses successfully. Every successful download was exactly 5 MiB and matched the generated SHA-256.
Isolation results
| Path | Observed result |
|---|---|
| Edge + raw CDP pipe, no Playwright | Native crash after 2–3 launches |
Edge + raw CDP pipe, allowAndName |
Same native crash |
| Edge + raw CDP port | 8/8 successful |
| Edge + Playwright attached over CDP port | 2/2 successful |
| Playwright-bundled Chromium 151 + persistent pipe context | 25/25 successful |
| Edge raw CDP pipe, headed and headless | Both reproduce |
Calling download.save_as() is not required. The standalone harness reproduces by polling the generated download directory and the Edge process; it does not call a Playwright download API.
Native crash signature
Independent dumps from headed, headless, and standalone raw-CDP pipe runs resolved to the same instruction:
Exception: 0xC0000005 read access violation
Module: msedge.dll 152.0.4191.53
Module offset: 0x9D5C88B
Access address: near-null (0x18–0x21 across dumps; 0x1A in the validated run)
Expected behavior
The download should finalize and Edge should remain alive across repeated launches with the same profile, independently of the CDP transport.
Additional information
Repository, full control matrix, and sanitized evidence (revision 64b9baf42b7158053317a985d8a564724481203a):
Launching Edge with --remote-debugging-port and attaching over CDP is an effective mitigation. Could the Edge team investigate the native failure at msedge.dll + 0x9D5C88B and advise which component owns the pipe/profile-reuse interaction? Raw Crashpad dumps can be provided privately if useful.
Activity
0xadada commentedon Sep 15, 2026
Confirmed this is happening in Microsoft Edge 154.0.4258.18 beta
hibestnick commentedon Sep 18, 2026
Cross-posting two results from the Chrome side that may help bound this, since this issue already isolated the transport (
--remote-debugging-pipevs--remote-debugging-port) with a Playwright-free raw-CDP harness.Environment: Windows 11 Pro build 26200, Google Chrome Stable 153.0.8010.48, Playwright Python 1.62.0 / 1.63.0. Browser exit code taken by holding a process handle (
OpenProcess→WaitForSingleObject→GetExitCodeProcess), consistently0xC0000005.1. It is not limited to branded builds. Playwright 1.63 ships bundled Chromium 153.0.8010.12, and that crashes too (5/5), whereas 1.62's bundled Chromium 151 does not. Together with Chrome Stable 153 crashing 19/20, this points at the Chromium 153 line rather than at branded packaging.
2. The trigger state is two specific profile files, and both are required. Using a "poisoned" profile (one launch, one download, closed) cloned against a "clean" profile (one launch, no download, closed):
Default/History(with rows indownloads) into a clean profile → no crashDefault/HistoryandDefault/shared_proto_db→ crashDefault/→ crash; poisoned root + cleanDefault/→ no crashPreferences,Cache,WebStorage,Networkindividually ruled out;DownloadMetadatadoes not existA profile that was launched once without downloading still downloads fine on the next launch, and only crashes on the launch after a download has been persisted — so "profile reuse" alone is not the trigger; a previously persisted download is.
3. Workaround. Emptying just
downloads,downloads_url_chainsanddownloads_slicesinDefault/Historyin one transaction before each launch (browser fully exited) gave 0/20 crashes over 60 downloads on 1.62 and 0/5 on 1.63, while leaving cookies and the rest of the profile untouched.shared_proto_dbis deliberately not touched — breaking either one of the two necessary conditions is enough.If a Chromium-side dump with a faulting module/offset for Chrome 153 would be useful, I can try to capture one (Playwright launches with
--disable-breakpad, so a plain run produces no Crashpad dump — worth noting for anyone concluding "no dump, no native crash").leahtu commentedon Sep 21, 2026
Thank you for your detailed report. The team is investigating the issue now.
savek-cc commentedon Sep 22, 2026
Still reproduces on Edge Stable 153.0.4234.48 (Windows 11 26200, Playwright 1.61.0, Python 3.14).
acceptDownloads=false, with a download that is never consumed, and in a separate tool that only drives the browser over--remote-debugging-pipewithout any download interception.--remote-debugging-portstays unaffected on the same machine and the same profile: 3 of 3 runs clean, headed and headless.savek-cc commentedon Sep 22, 2026
Crashpad reports from the runs above, for the address of the faulting site. 15 dumps from the same user-data-dir, Windows 10.0.26200:
msedge.dll+0x9d6c86bmsedge.dll+0x9a4cd1bmsedge.dll+0x43856e1The offset is identical across all dumps of a build, so it is one deterministic code site rather than heap corruption landing anywhere. The address being read (second exception parameter) is
0x18,0x20,0x21,0xffffffffffffffffor a value such as0x37400000388- a member access through a pointer that is null or already freed.The report above lists 152.0.4191.53 at
0x9D5C88B; these are two further builds, including the current 153 line.The dumps are process memory of a browser with live sessions, so they are not attached here. They can be shared privately on request.
savek-cc commentedon Sep 22, 2026
Symbolized against the public PDBs. Same crash site in both builds:
rax = 0, read at0x18rax = 0x0000037400000370, read at0x37400000388Bucket
INVALID_POINTER_READ_c0000005_msedge.dll!DownloadItemModel::DownloadItemModel, failure hash{feb330e6-40cd-7620-4af0-120ab1ce8dc2}.Stack from
!analyze -von the 153 dump (browser process, main thread):The download bubble's update service constructs a DownloadItemModel from a DownloadItem pointer that is null in one build and stale in the other, while iterating its merged caches after the item's target has been resolved. A null pointer in one crash and a garbage pointer in another at the same instruction fits a use-after-free rather than a missing null check.
Two frames in the raw output (
edge::webshot::EncodedImageData,media::ManifestDemuxer) are identical-code-folding artifacts, not real callers.Clear Chrome's download history before launch and refuse a profile in…
leahtu commentedon Sep 29, 2026
Hi everyone, quick update: this bug is resolved in Edge 155. The issue is tracked upstream here and fixed in this CL.