ErrLookup › Background articles › ArgumentNullException ("Value cannot be null"): when a .NET method rejects a null argument
ArgumentNullException ("Value cannot be null"): when a .NET method rejects a null argument
ArgumentNullException with the message "Value cannot be null" is thrown when .NET code passes a null reference for an argument a method requires to be non-null. It is raised by explicit fail-fast guards in libraries such as Newtonsoft.Json, Hangfire, Orleans, MAUI, LiteDB, Unity, and Polly, and its ParamName names the offending argument. This page covers the mechanism behind the whole family, how the message varies across libraries, and the causes and fixes that hold no matter which library threw it.
Distilled from 701 documented records across 41 repositories.
Background
ArgumentNullException is the canonical .NET exception for a method that received a null reference for an argument it requires to be non-null. Libraries raise it from an explicit guard clause near the top of a method, either `throw new ArgumentNullException(nameof(param))` or the newer `ArgumentNullException.ThrowIfNull(param)`, and the thrown instance carries a `ParamName` property identifying the offending argument. The base-class message format is "Value cannot be null. (Parameter 'X')".
The reason the family exists is fail-fast diagnosis. Without the guard, the same null would dereference several frames later as a NullReferenceException giving no clue which argument caused it. The records describe this repeatedly: Newtonsoft.Json funnels dozens of public entry points through a single `ValidationUtils.ArgumentNotNull` guard; LiteDB "fails fast on the public API surface so the caller sees the real cause"; dotnet/maui's RendererPool rejects a null `oldElement` at construction rather than letting it surface deep inside the swap logic. The guard converts a confusing downstream NRE into a precise, local signal.
From the caller's side the experience is uniform, but the message text varies by library and constructor overload. Several entries surface only the bare parameter name, because those guards used the paramName-only constructor: Newtonsoft's message "is literally the parameter name", CefSharp's is "browser", Hangfire's is "client" or "storage". Others show the full "Value cannot be null. (Parameter 'key')" form (BenchmarkDotNet). A few embed a descriptive sentence (Unity: "Cannot add custom dependency on an empty custom dependency."; ABP: "concerns should be provided!"). One group is actively misleading: dotnet/orleans throws ArgumentNullException for a non-positive TimeSpan timeout, so the message reads "Value cannot be null" for a value that is not null at all, and the records advise reading it as "invalid timeout value".
The family also varies in what counts as null and where the guard lives. LiteDB's Query.EQ treats empty and whitespace strings as null via IsNullOrWhiteSpace, and Unity's DependsOnCustomDependency rejects empty strings too. Some guards live in property setters (Hangfire's SqlServerStorageOptions.SqlClientFactory), some fire at object construction (RelayCommand, EnvironmentVariable, AssetIdentifier), and some are extension-method null-this checks (CefSharp, Hangfire's client.Schedule, Polly's timeoutProvider). What unifies them is the contract: a reference the method cannot operate on was supplied, and the library refuses to proceed.
Common causes
- Null argument passed to a guarded API.The dominant shape across the family. A caller supplies null for an argument the method requires: a null JsonReader or JsonWriter to a Newtonsoft serializer, a null browser to a CefSharp extension, a null binding or oldElement to a MAUI renderer. The ArgumentNullException.ParamName names the offending argument.
- Required service or configuration not initialized.A dependency or setting the library expected at startup was null at call time: Hangfire with no JobStorage.Current configured, Orleans with a credential or IServiceProvider that was never resolved, an IBackgroundJobClient that DI never registered. The guard fires on the first use of the missing dependency.
- Silent null from reflection or runtime resolution.Type.GetType and assembly.GetType return null on an unresolved name, Assembly.GetEntryAssembly() returns null in some hosts and test runners, and a Roslyn ITypeSymbol resolves to null when a referenced assembly is missing. The null is then forwarded to a guard that rejects it.
- Manual or reflective construction of an internal type.Constructing an object the library normally builds internally, with a dependency the public path would have wired automatically: Hangfire's CoreBackgroundJobFactory via reflection with a null state machine, ClientExceptionContext without a real exception, the internal BackgroundJobFactory constructor with a null filter provider.
- Extension method invoked on a null instance.Extension methods execute against a null 'this' without instance dispatch, so CefSharp browser extensions, Hangfire's client.Schedule, and Polly's timeoutProvider throw ArgumentNullException with the receiver's parameter name when the instance was never assigned.
- Invalid value reported through the wrong exception type.A minority of guards use ArgumentNullException for a non-null but invalid value. dotnet/orleans throws it for a non-positive TimeSpan timeout, so the message says "cannot be null" about a value that is not null; the ParamName, not the message text, is the real clue.
What usually fixes it
- Read ParamName first. Across every record it identifies the offending argument, so start there before changing code; treat the descriptive or misleading message variants as secondary to the parameter name.
- Guard or coalesce at the boundary. Null-check or default the value before it reaches the guarded API: coalesce the source string before deserializing (Newtonsoft), validate field names at the controller boundary (LiteDB), or short-circuit before the call.
- Prefer the library's public entry points and standard constructors. Use the pipeline that wires dependencies automatically rather than manual or reflective construction, e.g. Hangfire's BackgroundJobFactory decorator, EventHubAdapterFactory.Create, or the parameterless BackgroundJobFactory() in DI.
- Register all required services and validate startup configuration. Configure storage, credentials, and providers before first use and assert their presence at startup: Hangfire storage, Orleans credentials and checkpointer factories, and IBackgroundJobClient in the container.
- Enable nullable reference types and treat the warnings as errors. `<Nullable>enable</Nullable>` moves most null-argument mistakes to compile time, which both Newtonsoft and BenchmarkDotNet recommend in their prevention guidance.
- Null-check reflection and runtime resolution results. When resolving types, assemblies, or members by name, check the result and report the missing name rather than forwarding null: prefer typeof(T) over Type.GetType(string), reference every assembly a struct's field type lives in (Uno), and avoid Assembly.GetEntryAssembly() for resource lookups (Hangfire).
Go deeper
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Documented occurrences
- {parameterName}(JamesNK/Newtonsoft.Json)
- stateMachine(HangfireIO/Hangfire)
- type(unoplatform/uno)
- field(litedb-org/LiteDB)
- oldElement(dotnet/maui)
- context(HangfireIO/Hangfire)
- storage(HangfireIO/Hangfire)
- factory(HangfireIO/Hangfire)
- exception(HangfireIO/Hangfire)
- value(HangfireIO/Hangfire)
- Member '{member.GetPath()}' not found in type '{_entity.ForType.Name}' (use IncludeFields in BsonMapper)(litedb-org/LiteDB)
- context(HangfireIO/Hangfire)
- Value cannot be null. (Parameter '{propertyName}')(dotnet/orleans)
- filterProvider(HangfireIO/Hangfire)
- binding(dotnet/maui)
- serviceProvider(dotnet/orleans)
- execute(lucasg/Dependencies)
- checkpointerFactory(dotnet/orleans)
- type(Unity-Technologies/UnityCsReference)
- Shell Content Page is Null(dotnet/maui)
…and 681 more across the corpus — use search.
Honest provenance: generated on 2026-08-13 from AI-assisted analysis of the linked records. See how records are made.