Practical examples of debugging null pointer exceptions in C#
Real-world examples of debugging null pointer exceptions in C
Let’s start where developers actually live: stack traces and broken code. Here are several real examples of debugging null pointer exceptions in C# that mirror what you’ll see in production logs.
Example 1: Classic null on a property access
You’ve seen this one a thousand times:
public class User
{
public string Name { get; set; }
}
User user = null;
Console.WriteLine(user.Name); // Boom: NullReferenceException
In Visual Studio or Rider, the first step in debugging this null pointer exception is to set a breakpoint on the line that throws and inspect user in the Locals window. You’ll see user = null, which tells you the code that should initialize user never ran or returned null.
The real fix is not user ??= new User(); right before the WriteLine. That only hides the bug. The question you should ask is: Why was user null here at all?
Common root causes include:
- Data lookup returning null (e.g.,
FirstOrDefaultfrom Entity Framework) - Conditionals that skip initialization for certain inputs
- Misconfigured dependency injection where a service returns null
A safer pattern:
User? user = userRepository.GetById(id);
if (user is null)
{
// Decide the correct behavior: 404, default response, or error
throw new InvalidOperationException($"User with id {id} not found.");
}
Console.WriteLine(user.Name);
This moves the failure closer to the cause and makes debugging null pointer exceptions in C# much easier.
Example 2: Null from LINQ queries in production
Here’s a more realistic example of debugging null pointer exceptions in C# in a web API:
var order = dbContext.Orders
.FirstOrDefault(o => o.Id == orderId);
// Later
var total = order.TotalAmount; // NullReferenceException in production
This usually works fine in local testing, then blows up in production when someone requests an order that doesn’t exist.
A better pattern is to treat FirstOrDefault as a warning sign:
var order = await dbContext.Orders
.FirstOrDefaultAsync(o => o.Id == orderId, cancellationToken);
if (order is null)
{
return Results.NotFound(new { Message = $"Order {orderId} not found" });
}
var total = order.TotalAmount;
If nullable reference types are enabled (<Nullable>enable</Nullable> in your project file), annotate accordingly:
Order? order = await dbContext.Orders
.FirstOrDefaultAsync(o => o.Id == orderId, cancellationToken);
Now the compiler helps you avoid missing the null-check. This is one of the best examples of how language features can prevent null pointer exceptions before they ever hit runtime.
Example 3: ASP.NET Core dependency injection returning null
Another common example of debugging null pointer exceptions in C# shows up in ASP.NET Core controllers or minimal APIs when a dependency is misconfigured.
public class EmailController : ControllerBase
{
private readonly IEmailSender _emailSender;
public EmailController(IEmailSender emailSender)
{
_emailSender = emailSender; // Looks fine
}
[HttpPost("/send-email")]
public IActionResult SendEmail(EmailRequest request)
{
_emailSender.Send(request); // NullReferenceException here
return Ok();
}
}
In normal DI usage, _emailSender should never be null. If it is, you almost certainly forgot to register the service in Program.cs or Startup.cs:
builder.Services.AddScoped<IEmailSender, SmtpEmailSender>();
When debugging this null pointer exception, check:
- Is the service registered in the container?
- Is the interface type correct and in the same assembly you expect?
- Are you accidentally
new-ing up the controller manually in a test instead of using the test host and DI?
In tests, prefer the WebApplicationFactory or test server so DI behaves like production. That eliminates a whole class of null-related surprises.
Example 4: Async/await and race conditions with null
Async code can hide null pointer problems until you add concurrency. Here’s a realistic example of debugging null pointer exceptions in C# in an async scenario:
private User? _cachedUser;
public async Task<User> GetUserAsync(int id)
{
if (_cachedUser == null)
{
_cachedUser = await _userService.GetUserAsync(id);
}
return _cachedUser; // Occasionally throws when accessed by multiple callers
}
In a single-threaded test, this works. Under load, two requests might pass the if (_cachedUser == null) check before the first assignment completes, and _cachedUser may still be null when another thread reads it.
To fix:
private readonly SemaphoreSlim _userLock = new(1, 1);
private User? _cachedUser;
public async Task<User> GetUserAsync(int id)
{
await _userLock.WaitAsync();
try
{
if (_cachedUser == null)
{
_cachedUser = await _userService.GetUserAsync(id)
?? throw new InvalidOperationException("User service returned null");
}
return _cachedUser;
}
finally
{
_userLock.Release();
}
}
This example of debugging null pointer exceptions in C# shows that sometimes the fix is not just a null-check; it’s a concurrency fix.
Example 5: Nulls from JSON deserialization in APIs
With modern .NET, a lot of your data comes from JSON. That means the shape of your C# objects depends on client behavior, and clients are… creative.
public class CreateUserRequest
{
public string Email { get; set; }
public string Name { get; set; }
}
[HttpPost("/users")]
public IActionResult CreateUser([FromBody] CreateUserRequest request)
{
// Assumes client always sends Email and Name
var user = new User
{
Email = request.Email.Trim(), // NullReferenceException
Name = request.Name.Trim() // or here
};
// Save user
return Ok();
}
If the client omits Name, or sends null, you get a NullReferenceException. When you’re debugging this null pointer exception, the first thing to inspect is the raw JSON payload in logs or via a tool like Postman.
Safer patterns:
- Use validation attributes:
public class CreateUserRequest
{
[Required]
[EmailAddress]
public string Email { get; set; } = string.Empty;
[Required]
public string Name { get; set; } = string.Empty;
}
- Combine with nullable reference types and defensive checks:
if (!ModelState.IsValid)
{
return ValidationProblem(ModelState);
}
var user = new User
{
Email = request.Email.Trim(),
Name = request.Name.Trim()
};
The 2024–2025 trend in .NET backend development is leaning heavily toward strong validation, nullable annotations, and analyzers. These tools catch many null issues before they hit production. Microsoft’s official .NET docs on nullable reference types are a solid reference point: https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references.
Example 6: Collections that contain null elements
Not all null pointer exceptions come from a null variable. Sometimes the variable is fine, but its contents are not.
List<User> users = await _userService.GetUsersAsync();
foreach (var user in users)
{
Console.WriteLine(user.Name.ToUpper()); // Occasionally throws
}
``;
The list itself is non-null, but one or more `user` entries are null. This can happen when:
- Data mapping fails for some rows
- A projection in LINQ returns null for certain conditions
- Someone manually added `null` to the list
During debugging, inspect the collection contents in the Watch or Locals window. You’ll often see something like `[0] = User, [1] = null, [2] = User`.
A defensive pattern:
```csharp
foreach (var user in users.Where(u => u is not null))
{
Console.WriteLine(user!.Name.ToUpper());
}
Better yet, fix the data source so it never produces null entries unless there is a very clear semantic reason.
Example 7: Misusing the null-conditional operator
The null-conditional operator (?.) is fantastic, but it can hide bugs when used blindly. Here’s an example of debugging null pointer exceptions in C# that were “fixed” incorrectly:
// Original code
var city = order.Customer.Address.City; // NullReferenceException
// "Fix"
var city = order?.Customer?.Address?.City; // No exception, but now city is null
Now, instead of an exception, you have a silent data problem. Maybe the API returns an empty city, maybe it writes an incomplete address to a label. The bug is still there; it’s just quieter.
A better approach is to decide which nulls are valid and which are bugs:
if (order?.Customer?.Address is null)
{
throw new InvalidOperationException("Order is missing customer address.");
}
var city = order.Customer.Address.City
?? throw new InvalidOperationException("Customer city is required.");
This example of debugging null pointer exceptions in C# highlights a theme: you don’t always want to avoid exceptions. Sometimes you want sharper, more meaningful ones.
Example 8: Nullable reference types and static analysis in 2024–2025
Since C# 8, nullable reference types are one of the best examples of language-level help for debugging null pointer exceptions in C#. When properly enabled, the compiler warns you if you might be using a nullable reference without a null-check.
public string? GetUserName(int id)
{
var user = _userRepository.Find(id); // returns User?
return user?.Name; // Name is string?
}
public void PrintUserName(int id)
{
string name = GetUserName(id); // Compiler warning: possible null assignment
Console.WriteLine(name.Length); // Another warning
}
Instead of waiting for a runtime NullReferenceException, the compiler nudges you to handle the null case:
public void PrintUserName(int id)
{
string? name = GetUserName(id);
if (name is null)
{
Console.WriteLine("User not found");
return;
}
Console.WriteLine(name.Length);
}
Static analysis tools and analyzers are getting stronger every year. While many security-focused analyzers come from organizations like OWASP (https://owasp.org), their patterns—checking for unvalidated inputs, unsafe assumptions, and unchecked values—map neatly to avoiding null pointer exceptions as well.
Techniques and patterns drawn from these examples
The examples of debugging null pointer exceptions in C# above point to a few recurring patterns that actually work in day-to-day development.
Prefer failing fast over hiding nulls
If a value should never be null for your logic to make sense, fail early with a clear exception. Patterns like ArgumentNullException.ThrowIfNull() are your friends.
public OrderService(IOrderRepository repository)
{
ArgumentNullException.ThrowIfNull(repository);
_repository = repository;
}
This turns a vague NullReferenceException deep in your call stack into a precise configuration error during startup.
Use nullable annotations consistently
Half-enabling nullable reference types is worse than not using them at all. Once you flip the switch, commit to annotating:
stringmeans “never null”string?means “can be null; caller must handle it”
This turns the compiler into a partner in debugging null pointer exceptions in C#, not an afterthought.
Log context when exceptions happen
When a NullReferenceException hits production, you rarely have a debugger attached. Structured logging with context is the difference between guessing and knowing.
try
{
var total = order.TotalAmount;
}
catch (NullReferenceException ex)
{
_logger.LogError(ex, "NullReferenceException in {Method}. OrderId={OrderId}",
nameof(CalculateTotal), order?.Id);
throw;
}
You still rethrow, but now your logs have the method name and key identifiers that make reproducing and debugging much faster.
Tests that intentionally hit null paths
One underrated strategy in 2024–2025 is writing tests that intentionally send bad or incomplete data: missing JSON fields, invalid IDs, null collections. These become living examples of debugging null pointer exceptions in C# because they encode the failure modes directly in your test suite.
For inspiration on defensive programming and error handling philosophy, it’s worth looking at broader software engineering discussions from universities like MIT (https://web.mit.edu/6.005/www/fa15/classes/08-defensive-programming/), even if they’re language-agnostic. The mindset transfers directly to C# null handling.
FAQ: examples of debugging null pointer exceptions in C
How do I find the exact line that caused a NullReferenceException in C#?
Use the stack trace from the exception; it shows the method and line number. In Visual Studio, double-click the stack trace entry in the Output or Exception dialog to jump to the line. Then inspect every reference on that line to see which one is null. This is usually the first step in most examples of debugging null pointer exceptions in C#.
What is a simple example of fixing a NullReferenceException?
A minimal example of debugging null pointer exceptions in C# is checking for null before using the value:
User? user = repository.GetUser(id);
if (user is null)
{
return NotFound();
}
return Ok(user.Name);
The key is to decide what the correct behavior is when the value is missing, rather than just adding a null-check everywhere.
Are nullable reference types enough to prevent all null pointer exceptions?
No. Nullable reference types dramatically reduce accidental null usage, but they don’t understand your entire runtime world: external APIs, databases, JSON payloads, and concurrency issues can still produce nulls in unexpected places. The best examples of debugging null pointer exceptions in C# combine nullable annotations with validation, logging, and good architecture.
Should I wrap my entire method in a try/catch for NullReferenceException?
Generally, no. Catching NullReferenceException broadly is a red flag. It hides real bugs and makes debugging harder. Instead, catch it only around very narrow, well-understood operations if you must, and log enough context to fix the root cause.
What tools help with debugging null pointer exceptions in C# in 2024–2025?
Modern IDEs like Visual Studio and JetBrains Rider provide excellent debugger support, including data tips, watch windows, and nullable analysis. Static analyzers, Roslyn-based code analyzers, and nullable reference types all help you avoid many null pointer issues before runtime. Together, they turn the scattered examples of debugging null pointer exceptions in C# into repeatable, predictable workflows.
Related Topics
Practical examples of debugging null pointer exceptions in C#
Practical examples of testing strategies to prevent null pointer exceptions
Practical examples of how to identify null pointer exceptions in Python
Real-world examples of null pointer exceptions in SQL queries
Best examples of comparing null pointer exceptions vs. other exceptions in real code
Practical examples of using Optional to avoid null pointer exceptions in Java
Explore More Null Pointer Exceptions
Discover more examples and insights in this category.
View All Null Pointer Exceptions