dotnet/efcore · error · InvalidOperationException
The key on the entity type ' ' cannot be configured because…
Error message
The key {keyProperties} on the entity type '{entityType}' cannot be configured because the property '{property}' is contained in a complex type mapped to a JSON column. Keys cannot reference properties that are stored inside a JSON document. What it means
ValidateKey throws KeyPropertyInJsonComplexType when any property of a key is declared on a complex type that is mapped to a JSON column. Keys are relational concepts that must map to real columns; a property stored inside a JSON document cannot participate in a primary/alternate key, so the validator blocks this at finalization.
Solutions
- Move the key property out of the JSON-mapped complex type onto the owning entity as a real column.
- Drop the HasKey call referencing properties inside the JSON complex type; keys cannot live in JSON.
- If you need identity over JSON content, store a derived real column (e.g. a hash) and key on that instead.
Example fix
// before
modelBuilder.Entity<Customer>()
.OwnsOne(c => c.Address, a =>
{
a.ToJson("address");
a.Property(p => p.PostalCode);
});
modelBuilder.Entity<Customer>().HasAlternateKey(c => c.Address.PostalCode); // throws
// after — promote to a real column on Customer
modelBuilder.Entity<Customer>().Property(c => c.PostalCode).HasColumnName("postal_code");
modelBuilder.Entity<Customer>().HasAlternateKey(c => c.PostalCode); Defensive patterns
Strategy: validation
Validate before calling
foreach (var keyProp in key.Properties)
if (keyProp.DeclaringType is IComplexType ct && ct.IsMappedToJson())
throw new InvalidOperationException($"Key property {keyProp.Name} is in a JSON complex type."); Type guard
static bool KeyReferencesJsonProperty(IKey k)
=> k.Properties.Any(p => p.DeclaringType is IComplexType ct && ct.IsMappedToJson()); Prevention
- Never define keys (HasKey) over properties inside a JSON-mapped complex type.
- Promote identifying properties onto the owning entity as real columns before keying.
- When converting owned types to JSON, audit existing HasKey/HasAlternateKey calls.
When it happens
Trigger: Defining a key (HasKey) where one of the key properties lives on a ComplexType whose ComplexProperty is configured with ToJson. The check iterates key.Properties and inspects each property.DeclaringType — if it is IComplexType && complexType.IsMappedToJson(), the key is rejected.
Common situations: Promoting a nested JSON property to part of a key after switching to ToJson mapping; scaffolding code that adds keys to complex types before configuring JSON; value objects used as keys then migrated into a JSON column.
Related errors
- Complex property ' ' cannot have both a JSON column name ('…
- Complex property ' ' cannot use 'HasJsonPropertyName()'…
- Complex property ' ' is mapped to JSON but its containing…
- The complex collection property
- Both properties ' ' and ' ' on entity type ' ' are mapped…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/9244b03da75a397b.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:228
{
throw new InvalidOperationException(
RelationalStrings.AutoLoadedJsonProperty(property.Name, structuralType.DisplayName()));
}
}
/// <inheritdoc />
protected override void ValidateKey(
IKey key,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
base.ValidateKey(key, logger);
foreach (var property in key.Properties)
{
if (property.DeclaringType is IComplexType complexType
&& complexType.IsMappedToJson())
{
throw new InvalidOperationException(
RelationalStrings.KeyPropertyInJsonComplexType(
key.Properties.Format(),
key.DeclaringEntityType.DisplayName(),
property.Name));
}
}
ValidateDefaultValuesOnKey(key, logger);
ValidateValueGeneration(key, logger);
}
/// <summary>
/// Validates a primitive collection property.
/// </summary>
/// <param name="property">The property to validate.</param>
/// <param name="logger">The logger to use.</param>
protected override void ValidatePrimitiveCollection(
IProperty property,View on GitHub (pinned to 3a2006ef56)