{"record":{"id":"c9f19130f01894aa","repo":"dotnet/orleans","slug":"the-configured-azure-table-journal-client-provider","errorCode":null,"errorMessage":"The configured Azure Table journal client provider returned null.","messagePattern":"The configured Azure Table journal client provider returned null\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs","lineNumber":988,"sourceCode":"    }\n\n    private ETag SetHeaderFromResponse(Response response, HeaderProviderState providerState)\n    {\n        // Force a reload before the next mutation if the service did not return the new header ETag.\n        if (response.Headers.ETag is { } eTag)\n        {\n            SetHeader(eTag, providerState);\n            return eTag;\n        }\n\n        SetHeader(eTag: default, providerState: default);\n        return default;\n    }\n\n    private TableClient GetTableClient()\n    {\n        var client = _shared.TableClientProvider.GetTableClient();\n        return client ?? throw new InvalidOperationException(\"The configured Azure Table journal client provider returned null.\");\n    }\n\n    private static string FormatRowKey(string generation, long sequence)\n        => string.Create(CultureInfo.InvariantCulture, $\"{generation}-{sequence:D12}\");\n\n    private static string[] CreateChunkPropertyNames()\n    {\n        var names = new string[MaxChunksPerEntity];\n        for (var i = 0; i < names.Length; i++)\n        {\n            names[i] = string.Create(CultureInfo.InvariantCulture, $\"Data{i:D2}\");\n        }\n\n        return names;\n    }\n\n    private HeaderState CreateHeaderState(TableEntity entity)\n    {","sourceCodeStart":970,"sourceCodeEnd":1006,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs#L970-L1006","documentation":"The configured ITableClientProvider for Azure Table journal storage returned null from GetTableClient. The shared layer (AzureTableJournalStorage.cs:985) treats a null client as a fatal configuration defect because there is no valid table endpoint to use. This comes from a custom TableClientProvider implementation, not the default InitializedTableClientProvider (which throws its own error 218 instead).","triggerScenarios":"A user-supplied TableClientProvider subclass's GetTableClient() returns null; GetTableClient() in AzureTableJournalStorage.cs:987 receives null and throws.","commonSituations":"A custom provider lazily creates a client but its factory returned null (e.g., missing config section, null connection string parsed as null); a DI registration that builds the provider with unresolved dependencies; a provider written to return null-on-error instead of throwing.","solutions":["Make the custom TableClientProvider.GetTableClient() never return null — throw a meaningful exception if the client cannot be constructed.","Verify the configuration values the provider reads (connection string, URI, credentials) are bound and non-null at startup.","Register the provider and its dependencies correctly in the DI container so construction succeeds."],"exampleFix":"// before\npublic override TableClient GetTableClient() => _client; // _client may be null\n\n// after\npublic override TableClient GetTableClient()\n    => _client ?? throw new InvalidOperationException(\"TableClient was not configured.\");","handlingStrategy":"validation","validationCode":"var client = provider.GetTableClient();\nif (client is null) throw new InvalidOperationException(\"TableClientProvider returned null at startup\");","typeGuard":"static bool IsTableClientProviderValid(TableClientProvider p)\n{\n    try { return p.GetTableClient() is not null; }\n    catch { return false; }\n}","tryCatchPattern":null,"preventionTips":["Make custom TableClientProvider.GetTableClient() throw, never return null.","Exercise the provider in a startup health check.","Bind connection configuration before constructing the provider."],"tags":["azure-table","configuration","table-client"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}