warning CS8602: Dereference of a possibly null reference. The compiler's
nullable analysis has found a variable that can be null at that point, and
you call a member on it. Check it for null first, or give it a fallback value; do not
silence it with ! unless you can prove the value is never null.
In a new project it is a warning and the build still succeeds, so the program can crash
later with a NullReferenceException. With TreatWarningsAsErrors
on, which many teams and CI pipelines use, the same line fails the build.
The error
...\Program.cs(3,29): warning CS8602: Dereference of a possibly null reference. [...\FixLab.csproj]
Build succeeded.
And the same code built with dotnet build --no-incremental -p:TreatWarningsAsErrors=true:
...\Program.cs(3,29): error CS8602: Dereference of a possibly null reference. [...\FixLab.csproj]
The project folder was shortened to ...; the rest is as printed.
Why it happens
The most common first meeting is Console.ReadLine():
Console.Write("Your name: ");
var name = Console.ReadLine();
Console.WriteLine($"Hello, {name.Trim()}!");
Console.ReadLine() is declared as returning string?, because it
really does return null when the input stream ends, for example when input
is redirected from an empty file or closed by the caller. The console template
sets <Nullable>enable</Nullable> in the project file, so the
compiler tracks that name may be null and warns at column 29, the
.Trim() call. Any other value whose type ends in ? is treated
the same way when you call a member on it without a check.
The fix
Console.Write("Your name: ");
var name = Console.ReadLine();
if (string.IsNullOrWhiteSpace(name))
{
Console.WriteLine("No name entered.");
return;
}
Console.WriteLine($"Hello, {name.Trim()}!");
After the check the compiler knows name is not null, so the warning goes away
and the empty case gets a real answer. This version built with warnings treated as errors,
and with the input closed it printed No name entered. instead of crashing.
Other honest fixes: a fallback with ?? ""
(var name = Console.ReadLine() ?? "";), or the null-conditional
name?.Trim() when null is an acceptable result.
The null-forgiving operator, name!.Trim(), removes the warning and changes
nothing at run time: if the value is null, the program still throws. Use it only where
you know more than the compiler does.
How it was reproduced
A dotnet new console project on .NET SDK 10.0.403 (net10.0, nullable and
implicit usings on as the template sets them, no packages). A plain
dotnet build succeeded with one CS8602 warning; adding
-p:TreatWarningsAsErrors=true and --no-incremental (an
incremental build skipped the compiler and passed) turned it into an error. The fixed
program built clean under the same switch.
Frequently asked
- How do I fix CS8602 dereference of a possibly null reference?
- Check the value before using it (if (x is null) return; or string.IsNullOrEmpty), give it a fallback with ??, or use ?. when null is acceptable. The ! operator only hides the warning.
- Why does Console.ReadLine() give a possible null warning?
- It is declared to return string? because it returns null at the end of the input stream, for example when input is redirected from an empty file or the input is closed.
- How do I make nullable warnings fail the build?
- Set <TreatWarningsAsErrors>true</TreatWarningsAsErrors> in a PropertyGroup of the project file. For a one-off check, dotnet build --no-incremental -p:TreatWarningsAsErrors=true does the same from the command line.
The sister warning for properties is covered in CS8618: non-nullable property must contain a non-null value. More decoded errors are in the Fixes category.