Overview
NuGet.Services.Validation.Issues is a small, focused library that defines the concrete validation issue types reported when the NuGet pipeline rejects a package or symbol upload. Each issue carries a ValidationIssueCode (an integer enum) plus any structured contextual data needed to render a meaningful error message to the package author.
The library targets both net472 and netstandard2.0, allowing it to be consumed by full-framework Gallery web services and .NET Standard validation worker processes alike.
Role in the System
Produced by validators
Signing, symbol, and policy validators create
ValidationIssue instances and persist them (code + serialized JSON data) to the validation database.Consumed by the Gallery
NuGetGallery reads persisted issue records and calls
ValidationIssue.Deserialize to reconstruct typed objects for display on the package page.Contract boundary
Sits between
NuGet.Services.Contracts (which owns IValidationIssue and ValidationIssueCode) and any service that needs to produce or render rich error payloads.Multi-framework shared library
Dual-targets
net472 + netstandard2.0 so it can be referenced by both legacy ASP.NET Gallery code and modern worker services without forking.Key Files and Classes
| File | Class / Type | Purpose |
|---|---|---|
ValidationIssue.cs | ValidationIssue (abstract) | Base class; owns static singleton instances for no-data issues, the IssueCodeTypes dispatch map, and the Deserialize / Serialize methods. |
NoDataValidationIssue.cs | NoDataValidationIssue | Sealed concrete type for all issue codes that carry no additional payload (e.g. PackageIsSigned, PackageIsZip64, all symbol error codes). |
ClientSigningVerificationFailure.cs | ClientSigningVerificationFailure | Carries a ClientCode and ClientMessage forwarded verbatim from the NuGet client signing APIs; JSON-compact properties "c" and "m". |
UnauthorizedCertificateFailure.cs | UnauthorizedCertificateFailure | Carries the SHA-256 thumbprint of the certificate that was rejected; JSON-compact property "t". |
ObsoleteTestingIssue.cs | ObsoleteTestingIssue | [Obsolete] type used only in tests; maps to ValidationIssueCode.ObsoleteTesting = 9999. |
Properties/AssemblyInfo.cs | — | Grants InternalsVisibleTo for the test project; supports both signed and unsigned builds via #if SIGNED_BUILD. |
Dependencies
NuGet Package References
| Package | Purpose |
|---|---|
Newtonsoft.Json | JSON serialization and deserialization of issue payload data via JsonConvert, [JsonProperty], and [JsonConstructor]. |
Internal Project References
| Project | What it provides |
|---|---|
NuGet.Services.Contracts | IValidationIssue interface and the ValidationIssueCode enum (integer codes 0–9 for package issues, 250–254 for symbol issues, 9999 for obsolete testing). |
Issue Code Reference
| Code | Value | Class | Has Payload |
|---|---|---|---|
Unknown | 0 | NoDataValidationIssue | No |
PackageIsSigned | 1 | NoDataValidationIssue | No |
ClientSigningVerificationFailure | 2 | ClientSigningVerificationFailure | Yes — client code + message |
PackageIsZip64 | 3 | NoDataValidationIssue | No |
OnlyAuthorSignaturesSupported | 4 | NoDataValidationIssue | No |
AuthorAndRepositoryCounterSignaturesNotSupported | 5 | NoDataValidationIssue | No |
OnlySignatureFormatVersion1Supported | 6 | NoDataValidationIssue | No |
AuthorCounterSignaturesNotSupported | 7 | NoDataValidationIssue | No |
PackageIsNotSigned | 8 | NoDataValidationIssue | No |
PackageIsSignedWithUnauthorizedCertificate | 9 | UnauthorizedCertificateFailure | Yes — SHA-256 thumbprint |
SymbolErrorCode_ChecksumDoesNotMatch | 250 | NoDataValidationIssue | No |
SymbolErrorCode_MatchingAssemblyNotFound | 251 | NoDataValidationIssue | No |
SymbolErrorCode_PdbIsNotPortable | 252 | NoDataValidationIssue | No |
SymbolErrorCode_SnupkgDoesNotContainSymbols | 253 | NoDataValidationIssue | No |
SymbolErrorCode_SnupkgContainsEntriesNotSafeForExtraction | 254 | NoDataValidationIssue | No |
ObsoleteTesting (obsolete) | 9999 | ObsoleteTestingIssue | Yes — test fields A, B |
Serialization Pattern
Issues are persisted as two separate columns: the integerValidationIssueCode and a JSON data string. The base class controls the full round-trip:
NoDataValidationIssue is not constructed via JSON deserialization. Its instances are either the pre-built static singletons on ValidationIssue or constructed directly from an issue code. The IssueCodesWithNoData set acts as a fast-path gate in Deserialize to skip JSON parsing entirely for these codes.Notable Patterns and Quirks
The dispatch map
IssueCodeTypes only contains entries for issue codes that have a custom payload class. All other codes fall through to the IssueCodesWithNoData fast path or resolve to ValidationIssue.Unknown. Adding a new payload-bearing issue requires updating both IssueCodeTypes and ValidationIssueCode in the contracts project.