Overview
Validation.Symbols is a background job (console executable) that runs as part
of the NuGet.org package validation pipeline. When a publisher uploads a symbol
package (.snupkg) alongside a regular NuGet package (.nupkg), this job is
triggered via an Azure Service Bus message to verify that the symbols are valid
before they are made publicly available for debugger consumption.
The job performs three layers of verification:
- ZIP safety check — ensures the
.snupkgarchive does not contain path traversal entries that could escape the extraction directory. - Structural match — confirms every
.pdbfile in the snupkg has a corresponding.dllor.exein the nupkg (no orphan symbol files). - Portable PDB + checksum validation — reads PE debug directory entries,
verifies the PDB is in Portable PDB format (magic bytes
BSJB), and cryptographically confirms the PDB checksum matches the embedded checksum record in the PE file.
Role in the NuGetGallery Ecosystem
Validation Orchestrator
Receives
SymbolsValidatorMessage from the orchestrator via Azure Service
Bus. Reports back Succeeded or Failed with structured issue codes.Azure Blob Storage
Downloads both the
.snupkg (from a URI) and the corresponding .nupkg
(from the packages or validation container) to perform cross-file checks.Validator State DB
Writes final validation status to the
ValidatorStatuses table via
IValidatorStateService, keyed by ValidatorName.SymbolsValidator.Feature Flags
Conditionally sends a queue-back message to the orchestrator after saving
status, controlled by
IFeatureFlagService.IsQueueBackEnabled().This job is registered as
ValidatorName.SymbolsValidator in the validation
orchestrator. The orchestrator manages retry logic and overall package
publication gating — this job only performs the symbol-specific checks.Key Files and Classes
Dependencies
NuGet Package References
Internal Project References
Notable Patterns and Implementation Details
Dual-container fallback for nupkg downloads.
SymbolsFileService first
checks the main packages blob container, then falls back to the validation
container. This handles the case where a symbol package is uploaded alongside
a nupkg that is still awaiting final publication (sitting in the validation
container rather than the live packages container).Checksum algorithm is multi-hash tolerant. A PE file may embed multiple
PdbChecksum debug directory entries using different hash algorithms
(e.g., SHA-256, SHA-384). The validator computes the PDB hash for each
algorithm found and accepts a match from any one of them, following the
Portable PDB checksum spec.
The 20-byte PDB ID region is zeroed before hashing, as required by the spec.DB save has a fixed 5-retry loop without exponential backoff.
SymbolsValidatorMessageHandler.SaveStatusAsync retries up to 4 times
(the loop condition is ++currentRetry < maxRetries where MaxDBSaveRetry = 5,
so the effective max is 4 attempts). If all retries fail, the message is
requeued, which means the validation will re-run. The service is therefore
idempotent by design — duplicate messages with a terminal state are detected
and dropped immediately.