dotnet/efcore · error · InvalidOperationException

An error occurred while reading a database value. The expect

Error message

An error occurred while reading a database value. The expected type was '{expectedType}' but the actual value was 'null'.

What it means

Materialization null mismatch: ThrowReadValueException reports 'expected type was X but the actual value was null' when the reader returns DBNull/null for a column whose expected CLR type is a non-nullable value type (after MakeNullable based on the column's nullability flag). EF treats this as a data integrity violation.

Source

Thrown at src/EFCore.Relational/Query/Internal/BufferedDataReader.cs:1934

                message = exception is NullReferenceException
                    || Equals(value, DBNull.Value)
                        ? RelationalStrings.ErrorMaterializingPropertyNullReference(entityType, propertyName, expectedType)
                        : exception is InvalidCastException
                            ? CoreStrings.ErrorMaterializingPropertyInvalidCast(entityType, propertyName, expectedType, actualType)
                            : RelationalStrings.ErrorMaterializingProperty(entityType, propertyName);
            }
            else
            {
                message = exception is NullReferenceException
                    || Equals(value, DBNull.Value)
                        ? RelationalStrings.ErrorMaterializingValueNullReference(expectedType)
                        : exception is InvalidCastException
                            ? RelationalStrings.ErrorMaterializingValueInvalidCast(expectedType, actualType)
                            : RelationalStrings.ErrorMaterializingValue;
            }

            throw new InvalidOperationException(message, exception);
        }
    }
}

View on GitHub (pinned to dbf9771522)

Solutions

  1. Make the CLR property nullable (int? / DateTime?) so NULL materializes without error.
  2. Ensure the column truly disallows NULL in the database and backfill existing NULLs.
  3. If NULL comes from a JOIN, switch to an inner join or project into a nullable type.
  4. Add a database DEFAULT / configure a value generator so the column is never NULL.

Example fix

// before - non-nullable property, DB returns NULL
public DateTime CreatedAt { get; set; }

// after - nullable property
public DateTime? CreatedAt { get; set; };
Defensive patterns

Strategy: validation

Validate before calling

foreach (var et in dbContext.Model.GetEntityTypes())
foreach (var p in et.GetProperties())
    if (!p.IsNullable && p.ClrType.IsValueType)
    {
        // ensure the DB column is NOT NULL and has a default; check data for stray NULLs
        var col = p.GetColumnName();
        Console.WriteLine($"Verify DB column {et.GetTableName()}.{col} has no NULLs for non-nullable property {p.Name}.");
    }

Try / catch

try { return ctx.Set<T>().ToList(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("actual value was 'null'"))
{ _logger.LogError(ex, "NULL read into non-nullable property; make property nullable or fix data."); throw; }

Prevention

When it happens

Trigger: A non-nullable value-type property receives a NULL from the database (column is NOT NULL in model but contains NULL in data, or the SQL/projection produced NULL); a computed/default column returning NULL for a non-nullable property; LEFT JOIN producing NULLs for a required value-type property.

Common situations: A NOT NULL column that actually has NULLs (data inconsistency); a LEFT JOIN feeding a struct property; a stored proc returning NULL for an int/DateTime/Guid property; default values not applied by the DB.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/9dd12f4f58bb0760. Report an issue: GitHub.