Skip to content
Latchkey

MSBuild "MSB3027 / MSB3021: Unable to copy file ... being used" in CI

A copy task could not write an output file because another process held it open. MSBuild retries and then fails with MSB3027/MSB3021. On CI this is usually a leftover process or two builds writing the same output.

What this error means

Build fails with MSB3021/MSB3027 saying it could not copy a DLL/exe "because it is being used by another process", often after retries. It can be intermittent when concurrent jobs share an output path or a prior process did not exit.

MSBuild output
error MSB3021: Unable to copy file "obj/Release/net8.0/MyApp.dll" to
"bin/Release/net8.0/MyApp.dll". The process cannot access the file because it is
being used by another process.

Common causes

A leftover process holds the output open

A previous test or app run (or a dangling dotnet server process) still has the DLL/exe open, so the copy cannot overwrite it.

Concurrent builds share an output directory

Two jobs building into the same bin/obj path on a shared runner race to write the same file, locking each other out.

How to fix it

Stop lingering processes / build servers

Kill stale build servers and any process holding the output before building.

Terminal
dotnet build-server shutdown
# ensure prior app/test processes have exited before rebuild

Isolate output per job

  1. Give each concurrent job its own checkout/output directory.
  2. Avoid running the app/tests and rebuilding into the same output simultaneously.
  3. On self-hosted runners, ensure jobs do not share bin/obj paths.

How to prevent it

  • Run dotnet build-server shutdown if stale servers lock outputs.
  • Use isolated, per-job output directories on shared runners.
  • Ensure app/test processes exit before a rebuild copies their outputs.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →