C# CS8602 — Dereference of a Possibly Null Reference
Fix CS8602 nullable warnings by adding a real null check, using the null-forgiving operator only with proof, and annotating nullability correctly.
Symptoms
- Warning CS8602: Dereference of a possibly null reference
- Warnings appear only after enabling nullable reference types
- Suppressing one warning moves it to a later line
Possible causes
- Nullable reference types are enabled and the value may legitimately be null
- A helper returns a possibly-null value that the caller dereferences
- A null check exists but the compiler cannot track it across a method boundary
Diagnosis steps
Locate the dereference and its source
dotnet build /p:TreatWarningsAsErrors=true -warnaserror:CS8602Interpretation
Turning the warning into an error pins the exact line and prevents it from moving.
Inspect the flow analysis
dotnet build -warnaserror 2>&1 | grep CS8602Interpretation
The warning line shows which value the analyzer believes can be null.
Root cause
With nullable reference types enabled, the compiler tracks null-state flow. CS8602 is reported when a dereference occurs while the analyzer cannot prove the value is non-null on that path.
Fix
Add an explicit null check and return or throw early, use is not null patterns, and reserve the null-forgiving `!` for cases where non-null is guaranteed by construction with a short comment explaining why.
Risk note
Blanket use of the null-forgiving operator turns a compile-time warning into a runtime NullReferenceException.
Verify the fix
Build with warnings as errors and confirm CS8602 is gone; add a unit test passing null and asserting a controlled ArgumentNullException or default.
Symptoms
When you hit “C# CS8602 — Dereference of a Possibly Null Reference”, guessing wastes time. The guide below follows evidence: reproduce the symptom, run targeted diagnostics, identify the root cause, apply the fix, and verify it with concrete checks.
Observed symptoms include:
- Warning CS8602: Dereference of a possibly null reference
- Warnings appear only after enabling nullable reference types
- Suppressing one warning moves it to a later line
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Locate the dereference and its source
dotnet build /p:TreatWarningsAsErrors=true -warnaserror:CS8602
Turning the warning into an error pins the exact line and prevents it from moving.
Step 2: Inspect the flow analysis
dotnet build -warnaserror 2>&1 | grep CS8602
The warning line shows which value the analyzer believes can be null.
Likely contributors, in order of frequency:
- Nullable reference types are enabled and the value may legitimately be null
- A helper returns a possibly-null value that the caller dereferences
- A null check exists but the compiler cannot track it across a method boundary
Root Cause
With nullable reference types enabled, the compiler tracks null-state flow. CS8602 is reported when a dereference occurs while the analyzer cannot prove the value is non-null on that path.
The Fix
Add an explicit null check and return or throw early, use is not null patterns, and reserve the null-forgiving ! for cases where non-null is guaranteed by construction with a short comment explaining why.
Watch out: Blanket use of the null-forgiving operator turns a compile-time warning into a runtime NullReferenceException.
public string Greet(User? user)
{
if (user is null)
throw new ArgumentNullException(nameof(user)); // flow: non-null after
return $"Hello, {user.Name}";
}
// only when non-null is guaranteed by construction
var name = cache["user"]!.Name; // cache seeded above; safe by contract
Verify and Prevent
Build with warnings as errors and confirm CS8602 is gone; add a unit test passing null and asserting a controlled ArgumentNullException or default.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.