Repository navigation
Cosmos DB: DateTime serialization format causing errors in ordering and filtering #39113
Description
Activity
I'm a bot. Here is a possible related and/or duplicate issue (I may be wrong):
Hi,
I'd like to work on this.
From the repro, the root cause looks like the DateTime being serialized in a
variable-width ISO 8601 form (trailing zeros dropped), which breaks lexicographic
ordering and comparisons on the server. This affects both the stored values and
the query parameters (e.g. @boundary in the log), so both would need the same
normalized format.Before starting, I plan to check whether the trimming happens in the EF Core
Cosmos provider's type mapping or in the Cosmos SDK serializer, given the linked
Azure/azure-cosmos-dotnet-v3#4904.Questions for the team:
- Is changing the default to a fixed-width format (e.g. yyyy-MM-ddTHH:mm:ss.fffffffZ)
acceptable, or would that be a breaking change for existing data? - If so, would you prefer this as opt-in, or as a change to the default?
Happy to go a different direction if you have one in mind.
- Is changing the default to a fixed-width format (e.g. yyyy-MM-ddTHH:mm:ss.fffffffZ)
UPDATE
Reproduction
The repro from the issue behaves as reported on a local build ofmain
(c2dcb0f): OrderBy returnsfractional-second, exact-second, and the
Timestamp > boundaryfilter returns 0 rows.Findings
There seem to be two independent places where a DateTime becomes JSON text,
and both currently produce the shortened form (no trailing zeros):- Stored values and SQL constants:
CosmosStructuralTypeSerializerand
CosmosTypeMapping.GenerateSqlLiteralcall the property's
JsonValueReaderWriter.ToJson(...), which for DateTime appears to be
JsonDateTimeReaderWriter(Utf8JsonWriter.WriteStringValue(DateTime)). - Query parameters:
SqlParameter.ApplycallsqueryDefinition.WithParameter(Name, Value),
so the SDK serializes the raw value throughJsonCosmosSerializer
(registered inSingletonCosmosClientWrapper), which uses default
System.Text.Json settings.SqlParameter.ToJsonStringdoes the same.
Because these are separate, fixing only one of them leaves stored values and the
parameter in different layouts, and comparisons still give wrong results. In my
local test, patching only the parameter side gave a filter count of 2 instead of 1.Experiment
As a proof of concept I made both paths write a fixed-width UTC format
(yyyy-MM-dd'T'HH:mm:ss.fffffff'Z'). On a fresh database the repro then returns
exact-second, fractional-secondand a filter count of 1. The branch is here:https://github.com/mohammedwed/efcore/tree/fix/cosmos-datetime-format
This is only a proof of concept. I have not tested other Kinds
(Local/Unspecified), DateTimeOffset, or other precisions beyond the repro.
I have also not checked whether earlier EF Core versions behave the same way.Questions before I go further
-
JsonDateTimeReaderWriterlives in the sharedEFCoreproject, so changing it
would affect relational JSON columns too. Would you prefer a Cosmos-specific
reader/writer or type mapping? -
Changing the default format means existing documents in the short format
would compare inconsistently with new ones. Should this be opt-in, a change to
the default, or handled some other way? -
For parameters, would you prefer routing them through the type mapping's
reader/writer so there is a single place that decides the format, instead of
configuring the serializer?
Happy to take a different direction if you have one in mind.
- Stored values and SQL constants:
Is changing the default to a fixed-width format (e.g. yyyy-MM-ddTHH:mm:ss.fffffffZ)
acceptable, or would that be a breaking change for existing data?It's acceptable, as long as it can still read existing data
If so, would you prefer this as opt-in, or as a change to the default?
Default.
JsonDateTimeReaderWriter lives in the shared EFCore project, so changing it
would affect relational JSON columns too. Would you prefer a Cosmos-specific
reader/writer or type mapping?It's ok to change the shared implementation.
Changing the default format means existing documents in the short format
would compare inconsistently with new ones. Should this be opt-in, a change to
the default, or handled some other way?They are already compared inconsistently, so I doubt that any existing apps would be affected by this. As a workaround a custom ReaderWriter can be used if necessary.
For parameters, would you prefer routing them through the type mapping's
reader/writer so there is a single place that decides the format, instead of
configuring the serializer?Yes, this is the preferred approach.
- added a commit that references this issue
on Sep 30, 2026
Bug description
DateTimes are serialized to ISO8601 dates but the trailing zeros are dropped in the second fractions. The means that the lexicographic ordering of the values doesn't match the correct ordering. This causes errors in ordering and filtering.
Related Azure/azure-cosmos-dotnet-v3#4904
Your code
Stack traces
Verbose output
EF Core version
10.0.12
Database provider
Microsoft.EntityFrameworkCore.Cosmos
Target framework
.NET 10.0
Operating system
Windows 11
IDE
No response