Skip to main content

    NuGet Trusted Signers: Fixing NU3034 After a Certificate Rotation

    NU3034 means the signing certificate is not on your allow list. Why Microsoft's September 2026 NuGet rotation triggers it, and how to fix it safely.

    DR
    Daniel Rehak
    ·
    12 min read
    ·
    Published September 25, 2026
    ·
    Last updated September 25, 2026

    The short answer

    NU3034 means NuGet found a package signature it could not match to any certificate fingerprint in your allow list. As of 23 September 2026 Microsoft signs new NuGet packages with a new author certificate, so a nuget.config that pinned only the three previous fingerprints now rejects them. The fix is to add the new fingerprint alongside the old ones, never to replace them, because every package published before that date still carries the certificate it was signed with. If the error disappeared after you deleted the trustedSigners section, read on: the default mode is accept, where an unrecognised signer installs silently as though the package were unsigned.

    How a certificate rotation turns a working NuGet allow list into an NU3034 errorTwo panels facing each other. The left panel, headed Your allow list in nuget dot config, lists three certificate fingerprints beginning 3F9001, AA12DA and 566A31, which were the Microsoft author fingerprints before the rotation. The right panel, headed The package in front of you, shows a package published on or after 23 September 2026 carrying a fingerprint beginning 9A1B13. An arrow between the panels is labelled compare SHA-256, and a gold band marks the result: no entry matches, so NuGet raises NU3034. A caption band across the bottom states that adding the new fingerprint fixes the error, while removing the old three would break every package signed before the rotation.A rotation puts an unlisted fingerprint in front of a fixed listYour allow listnuget.config, author "microsoft"3F9001EA…EECEAA12DA22…8A27566A3188…1353The package in front of youpublished 23 Sep 2026 onward9A1B131B…B630never on the listcompare SHA-256no matchNU3034Adding the fourth fingerprint clears the error.Replacing the first three breaks every package signed beforethe rotation — which is most of what you restore.
    Pinning is a fixed list checked against a moving target. Every rotation adds a row; nothing ever tells you to take one away.

    What does NU3034 actually mean?

    NU3034 is NuGet telling you that a signature exists and does not appear on the list of signatures you said you would accept. It is not a broken package, a corrupted download or an expired certificate — those have their own codes. It fires only where somebody deliberately configured an allow list, which is why most .NET projects have never seen it.

    Microsoft groups four messages under the single code, and it helps to know which one you got before you change anything:

    The message saysWhat it usually is
    no trusted signers were specifiedsignatureValidationMode is require but the trustedSigners section is empty or missing. Often a config file that did not get copied into the build container.
    the fingerprint does not match any in the allow listA rotation. The signer is who you expected; the certificate is newer than your list. This is the September 2026 case.
    the repository listed no signing certificatesA private feed that advertises repository signing but publishes nothing in its service index. A feed configuration problem, not yours.
    not repository signed by a certificate this repository listsThe package reached your feed without being countersigned, typically after a mirror or a manual upload.

    Only the second one is fixed by editing a fingerprint. The other three are worth reading carefully before anybody starts pasting hashes into a config file.

    What changed on 23 September 2026

    Microsoft moved to a new author-signing certificate for the NuGet packages it publishes. From that date the new certificate signs new packages; everything published earlier keeps the signature it already has. Nothing was revoked and nothing expired early. If you never configured a client policy, restore behaves exactly as it did the week before, because NuGet accepts all authors and repositories unless told otherwise.

    Two groups notice. The first pinned Microsoft in a trustedSigners section, usually alongside signatureValidationMode set to require. The second calls dotnet nuget verify with explicit --certificate-fingerprint arguments in a pipeline step. Both compare against a fixed list, and both hit a fingerprint that has never been on it.

    This is the second time Microsoft has announced a rotation of this certificate in recent years — the previous notice covered a change in August 2023 — and the pattern is visible in Microsoft's own documentation, where the example microsoft author entry already carried three fingerprints before this one. That accumulation is the correct end state, not clutter.

    Add the new fingerprint, keep the old ones

    The repair is one line of configuration, and the important part is what you do not touch. Append the incoming fingerprint to the existing microsoft author entry and leave the previous three in place. A NuGet package carries the signature it was given at publish time forever, so dropping an old fingerprint means every package signed under it stops validating.

    Either edit the config directly:

    <trustedSigners>
      <author name="microsoft">
        <!-- keep every fingerprint you already had -->
        <certificate fingerprint="3F9001EA83C560D712C24CF213C3D312CB3BFF51EE89435D3430BD06B5D0EECE"
                     hashAlgorithm="SHA256" allowUntrustedRoot="false" />
        <certificate fingerprint="AA12DA22A49BCE7D5C1AE64CC1F3D892F150DA76140F210ABD2CBFFCA2C18A27"
                     hashAlgorithm="SHA256" allowUntrustedRoot="false" />
        <certificate fingerprint="566A31882BE208BE4422F7CFD66ED09F5D4524A5994F50CCC8B05EC0528C1353"
                     hashAlgorithm="SHA256" allowUntrustedRoot="false" />
        <!-- and add the one in use from 23 September 2026 -->
        <certificate fingerprint="9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630"
                     hashAlgorithm="SHA256" allowUntrustedRoot="false" />
      </author>
    </trustedSigners>

    Or let the CLI append it for you. The subcommand you want is certificate, not author: when a trusted signer with that name already exists, the certificate item is added to it rather than replacing anything.

    dotnet nuget trust certificate microsoft \
      9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630 \
      --algorithm SHA256
    
    # on Windows with nuget.exe
    nuget trusted-signers Add -Name microsoft \
      -CertificateFingerprint 9A1B131BEE0605433056A4EA3815478A8E177961A968C6C0027C1093D1FEB630 \
      -FingerprintAlgorithm SHA256
    
    # confirm the entry now holds four fingerprints
    dotnet nuget trust list

    One gotcha that costs people ten minutes: dotnet nuget trust author does not take a fingerprint. Its second argument is a local path to a signed .nupkg, and it reads the certificate out of that file. dotnet nuget trust certificate is the one that takes a hash. They both end up writing an <author> element, which is where the confusion comes from.

    Do the same for any pipeline step that passes --certificate-fingerprint to dotnet nuget verify. That option can be supplied more than once, so pass all four rather than swapping one for another.

    Why deleting trustedSigners makes the error vanish

    Because it switches the check off. NuGet's signatureValidationMode defaults to accept, and in that mode the documentation is blunt: packages signed with untrusted certificates are treated as unsigned and install without any warning or error. An allow list only blocks anything when the mode is require, which is also the mode that refuses to run with an empty list. Remove the section, and a red build turns green while the guarantee you were buying disappears with it.

    What NuGet does with a signature it cannot match, in accept mode and in require modeA two by two grid. The columns are signer on the allow list and signer not on the allow list. The rows are signatureValidationMode set to accept, which is the default, and signatureValidationMode set to require. In accept mode a listed signer installs with its signature verified, while an unlisted signer installs anyway and is treated as unsigned with no warning or error; that cell is highlighted in gold as the quiet failure. In require mode a listed signer installs verified and an unlisted signer is blocked with NU3034. A note underneath explains that deleting the trustedSigners section moves you from the bottom row to the top row, which removes the error by removing the check.The error is the check working. Silence is not.signer on the listsigner not on the listacceptthe defaultrequireopt-ininstalls, signatureverifiedinstalls anywaytreated as unsigned,no warning, no errorinstalls, signatureverifiedblockedNU3034Deleting trustedSigners moves you from the bottom row to the top one.The build goes green because nothing is being checked.
    The gold cell is the one to worry about: in the default mode an unrecognised signer is not an error, it is a signature that stopped counting.

    This is worth checking even if you did not touch anything. Plenty of repositories carry a trustedSigners section that somebody added years ago without ever setting signatureValidationMode. Those projects have been sitting in the top-left cell the whole time — the list is there, it looks like policy in a code review, and nothing has ever been enforced. A rotation is a good moment to find out which cell you are actually in:

    # who do I currently trust, and with which fingerprints?
    dotnet nuget trust list
    
    # is the check actually switched on? an absent key means the default, accept
    grep -r "signatureValidationMode" nuget.config NuGet.config 2>/dev/null

    If the honest answer is that nobody meant to enforce anything, say so and remove the section deliberately. That is a defensible position. Leaving a list in place that no tool consults is the one outcome with no upside.

    Author trust has no sync. Repository trust does.

    NuGet lets you trust two different things, and only one of them can repair itself. A trusted repository is identified by a service index URL, and a repository publishes its current signing certificates there; dotnet nuget trust sync fetches that list and replaces what you stored. A trusted author is identified by nothing but fingerprints. There is no endpoint behind a publisher to ask, so there is nothing to sync.

    Repository trust can refresh itself from a service index; author trust has no such pathTwo horizontal lanes. The upper lane, headed repository trust, runs from the repository rotating its certificate, to the repository publishing the new list in its version 3 service index, to the consumer running dotnet nuget trust sync, ending in an up to date list. The lower lane, headed author trust, runs from the author rotating its certificate to a gold gap labelled no service index and nothing to sync, then to the consumer adding the fingerprint by hand, ending in an up to date list. The gold gap is the only manual step in either lane and is what makes an author rotation reach every consumer as a broken build.One lane refreshes itself. The other waits for you.repository trustrepositoryrotates a certpublishes it inthe service indexdotnet nugettrust synclist iscurrentauthor trustauthorrotates a certno service index,nothing to syncyou add thefingerprint by handlist iscurrentMicrosoft is trusted as an author, so its rotation travels the lower laneand arrives at each consumer as a failed restore.
    This is why the same incident repeats every few years rather than being fixed once: the gold box is a missing protocol, not a missing command.

    Microsoft is trusted as an author, which is why its rotation reaches consumers as a failed restore rather than as a background refresh. It also explains why the advice is always "add the fingerprint" and never "run sync". Note the destructive edge on sync too: the documentation describes it as deleting the current list and replacing it with the repository's. That is fine for a feed that publishes its full history, and it is not something to reach for casually.

    If your private feed repository-signs everything it serves, trusting the repository rather than each author is the lower maintenance choice — one entry, refreshable on demand, and it keeps working when a supplier rotates. You can narrow it further with an <owners> list so that only packages submitted by named accounts pass.

    Why CI failed and your laptop did not

    Signature verification during restore is not on everywhere. Windows always performs it and uses the system root store. On Linux it was off by default until the .NET 8 SDK, where it became on by default, with the DOTNET_NUGET_SIGNATURE_VERIFICATION environment variable flipping it either way. On macOS it is off by default during restore, and Microsoft's own guidance is to leave it that way.

    Whether NuGet verifies package signatures during restore, by operating system and .NET SDK versionThree panels. Windows: verification is always enabled during restore and uses the Windows root store. Linux, highlighted in gold as the panel that changed: before the .NET 8 SDK verification is off during restore unless the environment variable DOTNET underscore NUGET underscore SIGNATURE underscore VERIFICATION is set to true, and from the .NET 8 SDK it is on by default and that variable set to false turns it off. macOS: verification is off during restore by default, and Microsoft advises leaving it off. A band underneath notes that one repository can therefore pass on a developer machine and fail on a build agent without any configuration difference between them.The same nuget.config, three different answersWindowsalways verifiesduring restoreuses the Windowsroot storeLinuxbefore .NET 8 SDK:off unless opted in.NET 8 SDK onward:on by defaulttoggled by env varmacOSoff during restoreby defaultMicrosoft advisesleaving it offOne repository, one config, and the check only runs in some of the placesyou build. That is the whole "works on my machine" story.
    Worth knowing before you conclude the pin is fine: a laptop that never verifies will never tell you the list is stale.

    So a team on macOS laptops building into Linux containers on the .NET 8 SDK or later gets a clean local restore and a failing pipeline from an identical checkout. Nobody changed anything; the check simply runs in one place and not the other. Before you start bisecting commits, confirm where verification is actually enabled.

    The same asymmetry cuts the other way, and it is the more serious half. If your only enforcement is on a platform where verification is off, your allow list has never blocked a single package. Treat the build agent as the place the policy lives and the laptop as the place it is merely declared.

    Read the fingerprint off a package

    A fingerprint copied from a web page is only as trustworthy as the page — including this one. The point of pinning is to remove that dependency, so derive the value from a package you already have and use any published hash as a cross-check rather than as the source. It costs one command.

    # read the signature details, including the certificate SHA-256
    dotnet nuget verify ./Microsoft.Extensions.Logging.9.0.0.nupkg --verbosity detailed
    
    # or let the CLI write the entry straight from the package
    dotnet nuget trust author microsoft ./Microsoft.Extensions.Logging.9.0.0.nupkg

    Use a package you fetched before the change for an old fingerprint and one published after it for the new one. If the value you read matches what the announcement published, you have two independent sources agreeing and you can commit the config with a clear conscience. If it does not, you have learned something considerably more important than a build fix.

    Keep allowUntrustedRoot at false while you are in there. Setting it to true tells NuGet to accept a certificate that does not chain to a trusted root, which throws away the part of the check that the fingerprint does not cover. The documentation flags it as not recommended, and it tends to appear in configs as a leftover from somebody testing with a self-signed certificate.

    If you sign packages, you are next

    Everything above describes being on the receiving end. If you publish signed packages and anyone downstream pins you, you will hand them the same breakage — and under the current rules you will do it far more often than Microsoft just did. Certificates issued on or after 1 March 2026 are capped at 460 days under CA/Browser Forum ballot CSC-31, down from the old 39-month maximum.

    How the 460-day code signing validity ceiling shortens the gap between fingerprint changesTwo timelines drawn one above the other on the same scale. The upper timeline, labelled certificates issued before 1 March 2026, shows a single span of up to 39 months with one fingerprint change at the end. The lower timeline, highlighted in gold and labelled issued on or after 1 March 2026 under ballot CSC-31, shows the same period broken into spans of at most 460 days with a fingerprint change at the end of each, giving roughly three changes where there used to be one. A note underneath says that a publisher whose consumers pin fingerprints should publish the incoming one before signing with it.Shorter certificates mean more fingerprint changesissued before 1 March 2026 — up to 39 monthsone certificate1 changeissued on or after 1 March 2026 — at most 460 days eachcertificatecertificatecertificate3 changesIf people pin you, announce the incoming fingerprint before you sign with it.
    The dots are the moments somebody else's build breaks. Under the 460-day ceiling there are about three of them where there used to be one.

    Three practical consequences. Publish the incoming fingerprint before you start signing with it, so consumers can add it ahead of the first package that needs it. Say plainly that old fingerprints stay valid, because the instinct is to swap rather than append. And keep a dated list somewhere durable — release notes, a documentation page, anywhere that is not a blog post that scrolls away.

    Renewal itself is the other half of the planning. A 460-day certificate means a renewal cycle that now lands inside most annual budget and audit rhythms rather than outside them, and the hardware key requirement in force since June 2023 means the new key is generated fresh in a token, HSM or cloud signing service rather than copied from the old one. Our guide to OV and EV code signing certificates and how they are delivered covers which delivery model survives an unattended CI pipeline, which matters a great deal more once you are doing this every fifteen months.

    For the mechanics of producing a signed package in the first place — the .nupkg, the timestamp server, the token or cloud key — see how to sign a NuGet package. This article is the view from the consumer's side of that same signature.

    Frequently Asked Questions

    Answers to common questions about certificates and our services.

    What does NuGet error NU3034 mean?

    It means NuGet was told to accept only signatures on an allow list, and the signature in front of it is not on that list. Microsoft documents four messages under the one code: no trusted signers were specified at all, the certificate fingerprint matches nothing in the allow list, the repository claims everything is repository signed but published no certificates, and the package was not repository signed by a certificate the repository lists. The first two are what a fingerprint rotation produces.

    Did Microsoft's September 2026 certificate change break restore for everyone?

    No, and that is why the reports are patchy. Restore only breaks where somebody has explicitly opted into an allow list — a trustedSigners section pinning Microsoft by fingerprint, usually together with signatureValidationMode set to require, or a dotnet nuget verify call passing --certificate-fingerprint. Projects that never configured a client policy carry on as before, because NuGet accepts all authors and repositories by default.

    Should I delete the old Microsoft fingerprints once the new one works?

    No. Packages keep the signature they were given, so every Microsoft package published before the rotation still carries the previous certificate. Remove those fingerprints and you break restore for every one of them, including older versions you pin deliberately. The microsoft author entry in Microsoft's own documented example already carried three fingerprints before this rotation. Treat the list as append-only and prune it only when you are certain nothing you consume is still signed that way.

    Why does dotnet nuget trust sync not fix this?

    Because sync is a repository feature. It asks a package source for the certificate list it publishes in its service index and replaces the stored list with that. Author trust has no equivalent: there is no service index behind a person or a company, so nothing to query. When an author rotates a certificate, every consumer who pinned that author adds the new fingerprint by hand or stops validating them. That asymmetry, not the rotation itself, is what makes this recur.

    How do I find a package's signing certificate fingerprint?

    Take it from a package you already trust rather than from a web page. Run dotnet nuget verify against a .nupkg you downloaded and read the certificate SHA-256 out of the output, or point dotnet nuget trust author at that same file and let it write the entry for you. A fingerprint copied from an article is only as trustworthy as the article, and pinning is supposed to remove that kind of dependency, not add one.

    How often will a code signing certificate rotation force this again?

    More often than it used to. Certificates issued on or after 1 March 2026 are capped at 460 days under CA/Browser Forum ballot CSC-31, down from 39 months. A publisher who used to hand consumers a new fingerprint roughly every three years now does it at least every fifteen months. If people pin you, publish the incoming fingerprint before you start signing with it and expect both to be in circulation for a long while.

    Still Have Questions?

    Contact our support team with questions about certificates, installation, or technical issues.

    Signing packages your consumers can pin

    A fingerprint is only worth pinning if the identity behind it was checked. The Certum code signing certificates we resell are issued after organisation validation and delivered with the key generated in certified hardware, including a cloud signing option that works in an unattended pipeline. See the OV and EV code signing options and what each one verifies before it issues.

    Related reading