Skip to content

Edge 152 crashes with 0xC0000005 in msedge.dll during a CDP download over --remote-debugging-pipe after profile reuse #461

Closed

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 allow

On 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 allow

The 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):

https://github.com/ryo-whaletech/microsoft-edge-cdp-pipe-download-crash-repro/tree/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

  1. 0xadada commented on Sep 15, 2026

    @0xadada

    Confirmed this is happening in Microsoft Edge 154.0.4258.18 beta

  2. hibestnick commented on Sep 18, 2026

    @hibestnick

    Cross-posting two results from the Chrome side that may help bound this, since this issue already isolated the transport (--remote-debugging-pipe vs --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), consistently 0xC0000005.

    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):

    • transplanting only Default/History (with rows in downloads) into a clean profile → no crash
    • transplanting Default/History and Default/shared_proto_db → crash
    • clean profile root + poisoned Default/ → crash; poisoned root + clean Default/ → no crash
    • Preferences, Cache, WebStorage, Network individually ruled out; DownloadMetadata does not exist

    A 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_chains and downloads_slices in Default/History in 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_db is 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").

  3. leahtu commented on Sep 21, 2026

    @leahtu

    Thank you for your detailed report. The team is investigating the issue now.

  4. savek-cc commented on Sep 22, 2026

    @savek-cc

    Still reproduces on Edge Stable 153.0.4234.48 (Windows 11 26200, Playwright 1.61.0, Python 3.14).

    • Same pattern as reported: the first launch on a user-data-dir is clean, the second and third launch on the same directory exit with 0xC0000005 the moment a CDP-driven download is handed over. 2 of 3 runs.
    • Not tied to Playwright's download API: it also happens with acceptDownloads=false, with a download that is never consumed, and in a separate tool that only drives the browser over --remote-debugging-pipe without any download interception.
    • --remote-debugging-port stays unaffected on the same machine and the same profile: 3 of 3 runs clean, headed and headless.
    • Impact: where enterprise policy disables remote debugging over TCP, the port transport is not available, and there is then no working route for a CDP-driven download.
  5. savek-cc commented on Sep 22, 2026

    @savek-cc

    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:

    Edge build dumps exception address
    152.0.4191.66 12 0xC0000005, read msedge.dll+0x9d6c86b
    153.0.4234.48 2 0xC0000005, read msedge.dll+0x9a4cd1b
    152.0.4191.66 1 0x80000003 msedge.dll+0x43856e1

    The 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, 0xffffffffffffffff or a value such as 0x37400000388 - 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.

  6. savek-cc commented on Sep 22, 2026

    @savek-cc

    Symbolized against the public PDBs. Same crash site in both builds:

    msedge!DownloadItemModel::DownloadItemModel+0x87
    488b4018   mov rax, qword ptr [rax+18h]
    
    • 153.0.4234.48: rax = 0, read at 0x18
    • 152.0.4191.66: rax = 0x0000037400000370, read at 0x37400000388

    Bucket INVALID_POINTER_READ_c0000005_msedge.dll!DownloadItemModel::DownloadItemModel, failure hash {feb330e6-40cd-7620-4af0-120ab1ce8dc2}.

    Stack from !analyze -v on the 153 dump (browser process, main thread):

    msedge!DownloadItemModel::DownloadItemModel+0x87
    msedge!DownloadBubbleUpdateService::CacheManager::UpdateDisplayInfoForDownloadItem+0x8a
    msedge!DownloadBubbleUpdateService::CacheManager::IterateOverMergedCaches+0x132
    msedge!DownloadBubbleUpdateService::CacheManager::UpdateDisplayInfo+0x1d9
    msedge!DownloadBubbleUpdateService::CacheManager::AddItemToCacheImpl<...>+0x390
    msedge!DownloadBubbleUpdateService::CacheManager::MaybeAddDownloadItemToCache+0x19e
    msedge!DownloadBubbleUpdateService::CacheManager::OnDownloadItemUpdated+0x9f
    msedge!DownloadBubbleUpdateService::OnDownloadUpdated+0xf4
    msedge!download::DownloadItemImpl::UpdateObservers+0x147
    msedge!download::DownloadItemImpl::OnTargetResolved+0x42
    

    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.

  7. leahtu commented on Sep 29, 2026

    @leahtu

    Hi everyone, quick update: this bug is resolved in Edge 155. The issue is tracked upstream here and fixed in this CL.

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