Describe the Problem
Reproducible or Determinstic builds provide a very nice set of security advantages to a piece of software:
- Security and verification: It becomes possible to detect and deal with a whole new class of attacks in the supply chain - including on build servers. It becomes easier to verify items like SBOMs.
- Increasing user trust: Users can trust the binaries they have matches the sources, reducing risks of backdoors and other vulnerabilities.
- Auditing and Compliance: It becomes easier to verify that the sources and binaries match for compliance reasons.
For more details, see https://en.wikipedia.org/wiki/Reproducible_builds and https://reproducible-builds.org/
Describe the Solution
It should be possible to build .NET in a way that the build can be reproduced by others. The general guidelines for making this happen are described at https://reproducible-builds.org/docs/commandments/.
It's okay to requires some extra set up - such as an env var like SOURCE_DATE_EPOCH - to make this happen.
Ideally, this should be the default configuration of building. But a custom configuration, or custom build flags to enable this behaviour, would be fine as a starting point (and maybe even as end-point, depending on the number/complexity).
Additional Context
.NET:
Arch Linux: https://wiki.archlinux.org/title/Reproducible_builds
Debian: https://wiki.debian.org/ReproducibleBuilds and https://lists.debian.org/debian-devel-announce/2026/05/msg00001.html:
we've decided it's time to say that Debian must ship reproducible packages. Since yesterday, we have enabled our migration software to block migration of new packages that can't be reproduced [2] or existing packages (in testing) that regress in reproducibility.
Fedora: https://fedoraproject.org/wiki/Changes/ReproduciblePackageBuilds and https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/3OGIBZWPBB43QEVDXPEHNYEYJWMRPJ4E/
Red Hat: https://access.redhat.com/blogs/766093/posts/1976033
SuSE: https://www.zdnet.com/article/suse-bets-its-future-on-digital-sovereignty/
Timing
The primary driver for this from our side that Fedora is looking to start testing reproducible builds formally in 2025 (discussion). Fedora is going to report issues against software that doesn't comply with the reproducible-build guidelines by the end of 2025. Many other languages/runtimes - including Haskell, mingw and golang packages - are in the same position as .NET and are known to be non-reproducible at the moment. I don't expect Fedora to make reproducible builds a hard requirement in 2025.
Breakdown
Phase 1: Local - Reliance on wall-clock time, randomness/GUIDs and file-system-ordering
This first phase is about rebuilding .NET VMR on the same identical system at the same paths multiple times and getting bit-identical SDKs.
- Arcade
- ASP.NET Core
- FSharp
- IdentityModel Extension
- MSBuild
- NuGet
- Roslyn
- Runtime
- SDK
- source-build-assets
- VMR
- vstest
Phase 2: Very host names, usernames and build paths
This phase is about rebuilding .NET VMR on different systems, and at different paths and getting bit-identical SDKs.
Nice-to-have
Questionable
Describe the Problem
Reproducible or Determinstic builds provide a very nice set of security advantages to a piece of software:
For more details, see https://en.wikipedia.org/wiki/Reproducible_builds and https://reproducible-builds.org/
Describe the Solution
It should be possible to build .NET in a way that the build can be reproduced by others. The general guidelines for making this happen are described at https://reproducible-builds.org/docs/commandments/.
It's okay to requires some extra set up - such as an env var like
SOURCE_DATE_EPOCH- to make this happen.Ideally, this should be the default configuration of building. But a custom configuration, or custom build flags to enable this behaviour, would be fine as a starting point (and maybe even as end-point, depending on the number/complexity).
Additional Context
.NET:
-deterministiccompile optionArch Linux: https://wiki.archlinux.org/title/Reproducible_builds
Debian: https://wiki.debian.org/ReproducibleBuilds and https://lists.debian.org/debian-devel-announce/2026/05/msg00001.html:
Fedora: https://fedoraproject.org/wiki/Changes/ReproduciblePackageBuilds and https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/3OGIBZWPBB43QEVDXPEHNYEYJWMRPJ4E/
Red Hat: https://access.redhat.com/blogs/766093/posts/1976033
SuSE: https://www.zdnet.com/article/suse-bets-its-future-on-digital-sovereignty/
Timing
The primary driver for this from our side that Fedora is looking to start testing reproducible builds formally in 2025 (discussion). Fedora is going to report issues against software that doesn't comply with the reproducible-build guidelines by the end of 2025. Many other languages/runtimes - including Haskell, mingw and golang packages - are in the same position as .NET and are known to be non-reproducible at the moment. I don't expect Fedora to make reproducible builds a hard requirement in 2025.
Breakdown
Phase 1: Local - Reliance on wall-clock time, randomness/GUIDs and file-system-ordering
This first phase is about rebuilding .NET VMR on the same identical system at the same paths multiple times and getting bit-identical SDKs.
FixThis doesn't actually seem to affect anything?UpdatePackageVersionTaskandReplacePackagePartsto keep already reproducible nuget packages reproducible.shared/Microsoft.AspNetCore.App/10.0.0-dev/Microsoft.AspNetCore.Components.Endpoints.dllandMicrosoft.AspNetCore.Http.Connections.dllhave a PE Time Stamp header that's different from build to build. (fixed by Treat all ProjectRefs to SharedFx projects as PrivateAssets=all aspnetcore#64863)RemoveSharedFrameworkDependenciestask should create deterministic packages. Fixed by Treat all ProjectRefs to SharedFx projects as PrivateAssets=all aspnetcore#64863#Stringsheap layout fsharp#19732This no longer reproduces.Mono.Cecil.dll,Mono.Cecil.Mdb.dll,Mono.Cecil.Pdb.dll,Mono.Cecil.Rocks.dllcontains many differences in the PE file itsef. TheImport Tables are at different RVAs, size of.textis different, and.rsrcand.relocare at different addresses.Native ELF binaries shipped with .NET have non-deterministic GNU build-id runtime#128157"Fix" is to use an identical native toolchain between buildsELF"Fix" is to use an identical native toolchain between builds.commentsection in shipped native binaries is non-deterministic runtime#128158DWARF"Fix" is to use an identical native toolchain between builds.debug_str"producer" string in shipped artifacts retaining debug info is non-deterministic runtime#128159targetPacks/Directory.Build.targetsinvokes ILAsm without-deterministic, causing non-reproducible reference assemblies source-build-assets#1662Flow Deterministic=true to repos dotnet#1618: PassDeterministic=trueproperty to all component repos.Deterministic=trueis already the default.DeterministicBuildOptOut=trueforvstest.projandnuget-client.proj( Why do nuget-client and vstest opt out of deterministic build? dotnet#1583 )[System.DateTime]::Nowin build scriptsFile glob pattern inBetter fix belongs in NuGet.ClientMicrosoft.TestPlatform.Build.sourcebuild*.nuspecresults in a non-deterministic order of files in the Microsoft.TestPlatform.Build nuget packagePhase 2: Very host names, usernames and build paths
This phase is about rebuilding .NET VMR on different systems, and at different paths and getting bit-identical SDKs.
Nice-to-have
SOURCE_BUILD_EPOCHfor timestamps of embedded files. Part of Re-enable support for deterministic pack NuGet/NuGet.Client#7020.psmdcpfiles ineng/tools/BuildComparer/Utils.cs?.psmdcpintest/Microsoft.DotNet.UnifiedBuild.Tests/NugetPackageContentTests.cs?Questionable
SetDeterministic=trueat each repo-level?Deterministic=trueis already the default at SDK-level.System.IO.Packaging?