dotnet/efcore · error · InvalidOperationException
An error occurred while reading a database value. See the in
Error message
An error occurred while reading a database value. See the inner exception for more information.
What it means
Thrown by ThrowReadValueException in RelationalPropertyExtensions.cs:2048 while EF Core reads a column value out of a DbDataReader and materializes it into an entity/primitive. It wraps the real database/contractor exception (cast failure, null into non-nullable, DBNull, converter error) as its InnerException and re-throws as InvalidOperationException with a contextual message. The library does this so a raw ADO.NET failure is reported with the entity type and property name rather than an opaque cast.
Source
Thrown at src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs:2048
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
? RelationalStrings.ErrorMaterializingValueNullReference(expectedType)
: exception is InvalidCastException
? RelationalStrings.ErrorMaterializingValueInvalidCast(expectedType, actualType)
: RelationalStrings.ErrorMaterializingValue;
}
throw new InvalidOperationException(message, exception);
}
/// <summary>
/// Gets the value of JSON property name used for the given property of an entity mapped to a JSON column.
/// </summary>
/// <remarks>
/// Unless configured explicitly, entity property name is used.
/// </remarks>
/// <param name="property">The property.</param>
/// <returns>
/// The value for the JSON property used to store the value of this entity property.
/// By default <see langword="null" /> is returned for key properties and for properties that
/// are not mapped to JSON.
/// </returns>
public static string? GetJsonPropertyName(this IReadOnlyProperty property)
=> (string?)property.FindAnnotation(RelationalAnnotationNames.JsonPropertyName)?.Value
?? (property.IsKey() || !property.DeclaringType.IsMappedToJson()
? nullView on GitHub (pinned to dbf9771522)
Solutions
- Inspect the InnerException (and its message) - it names the exact cast/conversion failure; the EF message only adds entity/property context.
- Compare the failing column's database type against the mapped CLR property (GetColumnType(), IsNullable) and reconcile the model or the schema with a migration.
- If a value converter is involved, verify ConverterClrType/ProviderClrType align with both the CLR property and the DB column type.
- Make the CLR property nullable (int?/DateTime?) if the column legitimately contains NULL, or add a database default/NOT NULL constraint with backfill.
- For transient/bad rows, project through a Select that normalizes the value before materialization.
Example fix
// before
public int StockCount { get; set; } // column is NULLABLE in DB -> NullReferenceException on read
// after (option A: make nullable)
public int? StockCount { get; set; }
// after (option B: ensure column NOT NULL with default)
// modelBuilder.Entity<Product>().Property(p => p.StockCount).HasDefaultValue(0); Defensive patterns
Strategy: try-catch
Validate before calling
// Cannot fully validate pre-query; mitigate by checking nullability up front.
foreach (var prop in context.Model.GetEntityTypes().SelectMany(e => e.GetProperties()))
{
if (!prop.IsNullable && prop.GetColumnType() is { } col
&& /* your schema metadata says column is nullable */ false)
{
// flag risk: non-nullable CLR property over a nullable column
}
} Try / catch
try
{
var result = await query.ToListAsync();
}
catch (InvalidOperationException ex)
when (ex.InnerException != null
&& (ex.InnerException is InvalidCastException
|| ex.InnerException is NullReferenceException
|| ex.InnerException is FormatException))
{
// ex.Message names the entity/property; ex.InnerException is the real cause.
logger.LogError(ex.InnerException, "Materialization failed reading {Message}", ex.Message);
throw new MyDomainReadException("Bad data in result set; see inner.", ex.InnerException);
} Prevention
- Keep the EF model and DB schema in lock-step via migrations so column nullability/types match.
- Use nullable CLR types for columns that can be NULL.
- Unit-test value converters with NULL, DBNull, and boundary values.
- Log the InnerException whenever you surface materialization errors.
When it happens
Trigger: Executing a query whose materializer calls the compiled value reader and the underlying DbDataReader.GetX()/value converter throws. Concrete triggers: a NULL lands on a non-nullable value-type property; a column value cannot be cast to the configured CLR type (e.g. string column into int); a value converter throws in ConvertFromProvider; the reader returns a type incompatible with the providerClrType.
Common situations: Database schema drifted from the model (column type changed, new NOT NULL without default), a value converter whose provider type mismatches the column, nullable DB column mapped to a non-nullable CLR property, regional/encoding issues producing unparseable values, importing legacy data with empty strings/DBNull where a numeric is expected.
Related errors
- The required column '{column}' was not present in the result
- The underlying reader doesn't have as many fields as expecte
- The type of the '{idProperty}' property on '{entityType}' is
- The type of the partition key property '{property}' on '{ent
- The property '{propertyType} {structuralType}.{property}' ha
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/52b01bea6cf0ddce.
Report an issue: GitHub.