Describe the bug
With several runners installed on one Windows machine under the same user account, a job's "Complete job" cleanup kills the MSVC PDB server (mspdbsrv.exe) that a concurrently running job on another runner is compiling against. That job's compiles fail with fatal error C1090: PDB API call failed, error code '23' (RPC to the PDB server failed; the Win32 code is 0x6BA "RPC server unavailable" or 0x6 "invalid handle").
mspdbsrv.exe is one instance per user account: cl.exe connects to the running instance if there is one and spawns it otherwise. So the first job to compile spawns it with its own RUNNER_TRACKING_ID, and every later job on the machine uses that instance. When the first job completes, the cleanup finds the process with its tracking id and kills it, taking down the other job's compiles in flight. Jenkins hit the same bug with its process tree killer (JENKINS-9104) and resolved it by exempting mspdbsrv.exe (core ProcessKillingVeto extension point since 1.625, used by the MSBuild plugin).
To Reproduce
- Install two runners on one Windows machine, running as the same user, with Visual Studio 2022.
- Start a C++ job (MSBuild Debug build, i.e.
/Zi) on each runner, the second a few minutes after the first, so the first finishes while the second is still compiling.
- The first job's "Complete job" prints
Terminate orphan process: pid (N) (mspdbsrv); within a second or two, every cl.exe of the second job with a PDB open fails with C1090 error 23. Files compiled after that succeed, since the next cl.exe spawns a fresh server.
Expected behavior
A job's cleanup shouldn't kill a process another still-running job on the machine is using. Options, in rough order of preference: exempt mspdbsrv.exe from the orphan cleanup as Jenkins does; or offer a configurable exclusion list for the cleanup; or at least document the workaround below in the self-hosted runner docs.
Workaround: set _MSPDBSRV_ENDPOINT_ to a per-runner value (e.g. the runner name) in each runner's environment. MSVC names the server's RPC endpoint after it, so each runner's compilers use a private instance, and the cleanup only ever kills the job's own server.
Runner Version and Platform
2.337.0, Windows 11 (build 26200), two runners on one machine as the same user. Visual Studio 2022 17.14 (MSVC 14.44).
Job Log Output
Killer job, "Complete job" step (runner 1):
2026-09-10T05:12:46.6664000Z Cleaning up orphan processes
2026-09-10T05:12:46.7339860Z Terminate orphan process: pid (9732) (MSBuild)
2026-09-10T05:12:46.7921309Z Terminate orphan process: pid (24136) (mspdbsrv)
Victim job, mid-compile (runner 2, same machine):
2026-09-10T05:12:48.5001440Z C:\...\lib1\a.cpp(409,1): error C1090: PDB API call failed, error code '23': (0x00000006) [E:\actions-runner-2\_work\proj\proj\build\proj.vcxproj]
2026-09-10T05:12:48.5154077Z C:\...\lib2\b.cpp(35,1): error C1090: PDB API call failed, error code '23': (0x00000006) [E:\actions-runner-2\_work\proj\proj\build\proj.vcxproj]
Describe the bug
With several runners installed on one Windows machine under the same user account, a job's "Complete job" cleanup kills the MSVC PDB server (
mspdbsrv.exe) that a concurrently running job on another runner is compiling against. That job's compiles fail withfatal error C1090: PDB API call failed, error code '23'(RPC to the PDB server failed; the Win32 code is 0x6BA "RPC server unavailable" or 0x6 "invalid handle").mspdbsrv.exeis one instance per user account:cl.execonnects to the running instance if there is one and spawns it otherwise. So the first job to compile spawns it with its ownRUNNER_TRACKING_ID, and every later job on the machine uses that instance. When the first job completes, the cleanup finds the process with its tracking id and kills it, taking down the other job's compiles in flight. Jenkins hit the same bug with its process tree killer (JENKINS-9104) and resolved it by exemptingmspdbsrv.exe(coreProcessKillingVetoextension point since 1.625, used by the MSBuild plugin).To Reproduce
/Zi) on each runner, the second a few minutes after the first, so the first finishes while the second is still compiling.Terminate orphan process: pid (N) (mspdbsrv); within a second or two, everycl.exeof the second job with a PDB open fails with C1090 error 23. Files compiled after that succeed, since the nextcl.exespawns a fresh server.Expected behavior
A job's cleanup shouldn't kill a process another still-running job on the machine is using. Options, in rough order of preference: exempt
mspdbsrv.exefrom the orphan cleanup as Jenkins does; or offer a configurable exclusion list for the cleanup; or at least document the workaround below in the self-hosted runner docs.Workaround: set
_MSPDBSRV_ENDPOINT_to a per-runner value (e.g. the runner name) in each runner's environment. MSVC names the server's RPC endpoint after it, so each runner's compilers use a private instance, and the cleanup only ever kills the job's own server.Runner Version and Platform
2.337.0, Windows 11 (build 26200), two runners on one machine as the same user. Visual Studio 2022 17.14 (MSVC 14.44).
Job Log Output
Killer job, "Complete job" step (runner 1):
Victim job, mid-compile (runner 2, same machine):