Skip to content

Troubleshooting

Aryeh Citron edited this page Apr 20, 2026 · 11 revisions

Common errors and how to fix them. For behavioural differences between the emulator and real Azure Cosmos DB, see Known Limitations.


Upgrading to 3.0.0 — CreateClient() / WrapClient() / CreateRouter() not found

Symptom: Compile error — CreateClient(), WrapClient(), or CreateRouter() are no longer accessible on FakeCosmosHandler.

Cause: These methods were made internal in v3.0.0 and replaced by the InMemoryCosmos API.

Fix: Replace manual FakeCosmosHandler wiring with InMemoryCosmos:

// Before (2.x)
var handler = new FakeCosmosHandler(container);
var client = handler.CreateClient();

// After (3.0.0)
using var cosmos = InMemoryCosmos.Create("my-container", "/pk");
var client = cosmos.Client;

See the full Migration Guide for multi-container, custom options, and fault injection patterns.


"Item must have an 'id' property"

Symptom: CreateItemAsync, UpsertItemAsync, or their stream variants throw:

Item must have an 'id' property (case-sensitive, lowercase). If your C# model uses PascalCase 'Id', ensure CosmosClientOptions.Serializer is configured with camelCase naming (e.g. CosmosJsonDotNetSerializer with CamelCasePropertyNamesContractResolver).

Cause: The Cosmos SDK serializes your C# object to JSON before sending it. If your model has public string Id { get; set; } (PascalCase), the default serializer produces { "Id": "..." } — but Cosmos requires lowercase "id".

Fix (recommended): Add [JsonProperty("id")] on the property:

using Newtonsoft.Json;

[JsonProperty("id")]
public string Id { get; set; }

This is the simplest approach and works with all integration approaches.

Alternative fix: Configure CosmosClientOptions.Serializer with a camelCase contract resolver. Note that CosmosJsonDotNetSerializer is not part of the public SDK — you need to supply your own CosmosSerializer implementation, or copy the one from the Azure Cosmos DB samples:

var client = new CosmosClient(connectionString, new CosmosClientOptions
{
    Serializer = new MyCustomCosmosSerializer(new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver()
    })
});

This error applies equally to all integration approaches (InMemoryCosmos.Create(), FakeCosmosHandler, and Dependency Injection methods) and the real Azure Cosmos DB service. See Getting Started — serialization note and Setup Guide — serialization for more context.


NullReferenceException in HandleUpsertAsync / HandleCreateAsync

Symptom: NullReferenceException when calling CRUD operations through FakeCosmosHandler.

Cause: Usually the same root cause as above — the serialized JSON doesn't contain "id" (lowercase), so partition key extraction or document indexing fails.

Fix: Apply the [JsonProperty("id")] fix or camelCase serializer described above.


Query returns empty results

Symptom: GetItemQueryIterator or LINQ queries return no items, even though items were inserted.

Possible causes:

  1. Partition key path mismatch. The container was created with a different partition key path than your production container. For example, your production container uses /customerId but the test uses the default /id.

  2. Cross-partition query not enabled. By default, queries target a single partition. If you pass a PartitionKey in QueryRequestOptions, only items in that partition are returned. Omit the partition key to run a cross-partition query.

  3. Serialization mismatch. Items were inserted with one casing but queried with another. Ensure serializer configuration is consistent across all operations.

Fix: Verify the partition key path matches your production configuration:

// Must match your Azure Cosmos container's partition key path
using var cosmos = InMemoryCosmos.Create("orders", "/customerId");

For a full list of supported query syntax, see SQL Queries.


"Container 'xxx' is not registered" / "Container 'xxx' not found"

v3.0.0 note: CreateRouter() is now internal. Use InMemoryCosmos.Builder().AddContainer(...) instead. The error message now returns a 404 CosmosException with the list of available containers.

Symptom: CosmosException (404) when accessing a container:

Container 'xxx' not found. Available containers: a, b, c.

Cause: Your production code calls client.GetContainer("db", "xxx"), but "xxx" is not registered.

Fix (3.0.0): Add the missing container to the builder:

using var cosmos = InMemoryCosmos.Builder()
    .AddContainer("orders", "/customerId")
    .AddContainer("customers", "/id")
    .AddContainer("xxx", "/id")  // ← add this
    .Build();

See Setup Guide — Direct Instantiation for the full pattern.


Change feed processor doesn't fire

Symptom: InMemoryChangeFeedProcessor doesn't invoke the delegate after inserting items.

Cause: The processor must be started explicitly and polls on a 50 ms interval internally. If your test completes before the poll cycle runs, the delegate won't fire.

Fix: Ensure you call StartAsync() and allow time for the poll cycle:

await processor.StartAsync();
// ... insert items ...
await Task.Delay(500); // allow poll cycle to complete
await processor.StopAsync();

The in-memory change feed has several known behavioural differences from real Cosmos DB, including FeedRange scoping and the stream handler variant. See Features — Change Feed for supported functionality.


"Failed to parse Cosmos SQL query"

Symptom: NotSupportedException when running a SQL query:

Failed to parse Cosmos SQL query: SELECT ...

Cause: The built-in SQL parser doesn't support the query syntax you're using. While it covers 120+ functions and most common patterns, some advanced or rarely-used Cosmos SQL syntax may not yet be implemented.

Fix: Check the SQL Queries page for the full list of supported clauses, operators, and functions. If your query uses unsupported syntax, consider:

  1. Filing an issue to request support.
  2. Rewriting the query using supported syntax.
  3. Falling back to LINQ-based queries if applicable.

TTL items not disappearing immediately

Symptom: Items with a TTL (time-to-live) are still returned by queries after they should have expired.

Cause: The emulator uses lazy TTL eviction — expired items are removed during reads and queries, not proactively on a background timer. This differs from real Cosmos DB, which evicts items in the background.

Fix: This is expected behaviour. Expired items are filtered out of query results and point reads. If you need to verify TTL expiry in tests, insert the item, advance past the TTL duration with Task.Delay, and then confirm the item is no longer returned. See Known Limitations for details.


.ToFeedIterator() throws ArgumentOutOfRangeException

Symptom: Calling .ToFeedIterator() on a LINQ query throws:

ArgumentOutOfRangeException: ToFeedIterator is only supported on Cosmos LINQ query operations

Cause: When using a raw container directly (not via FakeCosmosHandler), GetItemLinqQueryable<T>() returns a standard LINQ-to-Objects queryable. The SDK's .ToFeedIterator() only works on queryables created by its own CosmosLinqQueryProvider.

Fix: All recommended approaches (InMemoryCosmos.Create(), UseInMemoryCosmosDB(), UseInMemoryCosmosContainers()) use FakeCosmosHandler internally, which means .ToFeedIterator() works as-is. If you see this error, you're likely using an internal class directly. Migrate to one of the recommended patterns.

See How Does ToFeedIterator() Work? for details.


SDK compatibility check failed

Symptom: InvalidOperationException during test setup mentioning "SDK compatibility check failed":

SDK compatibility check failed (v3.x.x): expected 3 items from basic query but got 0. The Cosmos SDK may have changed its internal HTTP contract.

Cause: FakeCosmosHandler.VerifySdkCompatibilityAsync() runs a suite of checks to verify that the installed Cosmos SDK version is compatible with the handler's HTTP interception layer. A failure means the SDK version you're using has changed its internal HTTP contract in a way that FakeCosmosHandler doesn't yet support.

Fix:

  1. Check you're using a supported SDK version (3.58.0+).
  2. Update to the latest version of CosmosDB.InMemoryEmulator.
  3. If the issue persists, file an issue — the handler may need updating for new SDK internals.

Still stuck?

Clone this wiki locally