dotnet/orleans · critical · InvalidOperationException

Journal format key '{journalFormatKey}' resolved format '{jo

Error message

Journal format key '{journalFormatKey}' resolved format '{journalFormat.GetType().FullName}', but its FormatKey is '{journalFormat.FormatKey}'. Register the journal format using the same key it reports.

What it means

Thrown by ValidateJournalFormat when a keyed IJournalFormat was resolved, but its own FormatKey property does not match the key used to register/resolve it. The system requires the registration key and the format's self-reported key to agree, to prevent format/version mismatches that would corrupt journals.

Source

Thrown at src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorageProvider.cs:136

        catch (ArgumentException)
        {
            journalId = default;
            return false;
        }
    }

    private static void ValidateJournalFormat(IServiceProvider serviceProvider, string journalFormatKey)
    {
        var journalFormat = serviceProvider.GetKeyedService<IJournalFormat>(journalFormatKey);
        if (journalFormat is null)
        {
            throw new InvalidOperationException(
                $"Journal format key '{journalFormatKey}' requires keyed service '{typeof(IJournalFormat).FullName}', but none was registered.");
        }

        if (!string.Equals(journalFormat.FormatKey, journalFormatKey, StringComparison.Ordinal))
        {
            throw new InvalidOperationException(
                $"Journal format key '{journalFormatKey}' resolved format '{journalFormat.GetType().FullName}', but its {nameof(IJournalFormat.FormatKey)} is '{journalFormat.FormatKey}'. " +
                "Register the journal format using the same key it reports.");
        }
    }

    private static string ValidateJournalFormatKey(string? journalFormatKey)
    {
        if (string.IsNullOrWhiteSpace(journalFormatKey))
        {
            throw new InvalidOperationException("The configured journal format key must be non-empty.");
        }

        return journalFormatKey;
    }
}

View on GitHub (pinned to fca799fa70)

Solutions

  1. Register the format using the same key that its FormatKey property reports (read the property or docs to find the canonical key).
  2. Update the registration key to match after a format upgrade that changed FormatKey.
  3. Avoid inventing alias keys; use the format's documented key.

Example fix

// before
services.AddKeyedSingleton<IJournalFormat, JsonJournalFormat>('myJson'); // FormatKey is 'json'
// after
services.AddKeyedSingleton<IJournalFormat, JsonJournalFormat>('json'); // matches FormatKey
Defensive patterns

Strategy: validation

Validate before calling

var fmt = serviceProvider.GetRequiredKeyedService<IJournalFormat>(journalFormatKey);
if (!string.Equals(fmt.FormatKey, journalFormatKey, StringComparison.Ordinal))
    throw new InvalidOperationException($"Register the format under its own FormatKey '{fmt.FormatKey}'.");

Type guard

static bool KeyMatchesFormatKey(IServiceProvider sp, string key)
    => sp.GetKeyedService<IJournalFormat>(key) is { } f && string.Equals(f.FormatKey, key, StringComparison.Ordinal);

Prevention

When it happens

Trigger: An IJournalFormat implementation is registered under key A but its FormatKey property returns B; ValidateJournalFormat compares them with ordinal equality and throws.

Common situations: Registering a format under a custom alias instead of its canonical FormatKey; a versioned format whose FormatKey changed across an upgrade but the registration key was not updated; copy-paste of a registration with the wrong key.

Related errors


AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13). Data as JSON: /api/errors/25e2daf0b1279f91. Report an issue: GitHub.