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.