dotnet/orleans · critical · OrleansConfigurationException
Custom document id or partition key providers are not compat
Error message
Custom document id or partition key providers are not compatible with partition key path set to /GrainType
What it means
Thrown during Cosmos container initialization when the partition key path is /GrainType (GRAINTYPE_PARTITION_KEY_PATH) but a custom document ID or partition key provider is registered. The /GrainType partition strategy is an Orleans-managed scheme that expects the DefaultDocumentIdProvider without a custom partition key provider. Mixing the two is explicitly forbidden because it would produce inconsistent partition key assignments.
Source
Thrown at src/Azure/Orleans.Persistence.Cosmos/CosmosGrainStorage.cs:333
foreach (var idx in _options.StateFieldsToIndex)
{
var path = idx.StartsWith("/") ? idx[1..] : idx;
stateContainer.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = $"/\"State\"/\"{path}\"/?" });
}
}
const int maxRetries = 3;
for (var retry = 0; retry <= maxRetries; ++retry)
{
var containerResponse = await db.CreateContainerIfNotExistsAsync(stateContainer, _options.ContainerThroughputProperties);
if (containerResponse.StatusCode == HttpStatusCode.OK || containerResponse.StatusCode == HttpStatusCode.Created)
{
var container = containerResponse.Resource;
_partitionKeyPath = container.PartitionKeyPath;
if (_partitionKeyPath == GRAINTYPE_PARTITION_KEY_PATH &&
(_documentIdProvider is not DefaultDocumentIdProvider defaultProvider || defaultProvider.HasCustomPartitionKeyProvider))
throw new OrleansConfigurationException("Custom document id or partition key providers are not compatible with partition key path set to /GrainType");
}
if (retry == maxRetries || dbResponse.StatusCode != HttpStatusCode.Created || containerResponse.StatusCode == HttpStatusCode.Created)
{
break; // Apparently some throttling logic returns HttpStatusCode.OK (not 429) when the collection wasn't created in a new DB.
}
await Task.Delay(1000);
}
}
private async Task TryDeleteDatabase()
{
try
{
await _client.GetDatabase(_options.DatabaseName).DeleteAsync().ConfigureAwait(false);
}
catch (CosmosException dce) when (dce.StatusCode == HttpStatusCode.NotFound)
{View on GitHub (pinned to fca799fa70)
Solutions
- Choose one partition strategy: either use /GrainType path (remove custom IPartitionKeyProvider/IDocumentIdProvider registrations) or use a custom provider (change the container partition key path to something else like /PartitionKey).
- If you need custom partition keys, do not set the container's partition key path to /GrainType.
- Remove the ConfigurePartitionKeyProvider call if using the /GrainType default strategy.
- Delete and recreate the Cosmos container with the correct partition key path for the chosen strategy.
Example fix
// before: conflicting configuration
siloBuilder.AddCosmosGrainStorage("store", o =>
{
// container has /GrainType partition key
});
siloBuilder.Services.AddSingleton<IPartitionKeyProvider, MyPartitionKeyProvider>();
// after: pick one strategy
siloBuilder.AddCosmosGrainStorage("store", o =>
{
o.PartitionKeyPath = "/PartitionKey"; // custom provider strategy
}); Defensive patterns
Strategy: validation
Validate before calling
// At startup, verify partition key path and provider strategy are compatible
var partitionKeyPath = configuration["Orleans:Persistence:store:PartitionKeyPath"];
var hasCustomProvider = sp.GetService<IPartitionKeyProvider>() is not null
|| sp.GetKeyedService<IDocumentIdProvider>("store") is not DefaultDocumentIdProvider;
if (partitionKeyPath == "/GrainType" && hasCustomProvider)
throw new InvalidOperationException("Cannot use /GrainType partition with a custom ID/partition provider."); Try / catch
try { await host.StartAsync(ct); }
catch (OrleansConfigurationException ex) when (ex.Message.Contains("not compatible with partition key path"))
{
logger.LogCritical(ex, "Cosmos partition key path /GrainType conflicts with custom provider — choose one strategy.");
throw;
} Prevention
- Choose one partition strategy upfront: /GrainType default OR custom IDocumentIdProvider/IPartitionKeyProvider.
- Document the chosen partition strategy in the project's configuration docs.
- Do not mix ConfigurePartitionKeyProvider with /GrainType container setup.
- Delete and recreate the Cosmos container when switching partition strategies.
When it happens
Trigger: Cosmos container was created or found with PartitionKeyPath="/GrainType", and _documentIdProvider is not a DefaultDocumentIdProvider (or it is, but HasCustomPartitionKeyProvider is true — meaning an IPartitionKeyProvider was injected). This combination is detected during the Init lifecycle stage after CreateContainerIfNotExistsAsync.
Common situations: Developer configures UseCosmosGrainStorageWithGrainTypePartitionKeyPath (or sets the container partition key to /GrainType) but also calls ConfigurePartitionKeyProvider or AddPartitionKeyProvider to register a custom IPartitionKeyProvider. Mixing two partitioning strategies. Copy-paste config from one provider to another.
Related errors
- Provider type {providerType} must implement IDocumentIdProvi
- Connection string '{connectionName}' was not found.
- Orleans:AdvertisedIPAddress must contain the Container Apps
- {key} must be a valid TCP port.
- graintype, siloNameFilter, and upperbound must be specified
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/71a9d4757f6a4f21.
Report an issue: GitHub.