microsoft/garnet · critical · RedisSerializationException

Unable to find property in {typeof(Options)} named {redisOpt

Error message

Unable to find property in {typeof(Options)} named {redisOptionAttr.GarnetOptionName} that matches {typeof(Options)} property {prop.Name}

What it means

Thrown by RedisConfigSerializer.TryPopulateOptions when a RedisOptions property's RedisOptionAttribute specifies a GarnetOptionName that does not exist as a property on the Options class. This is a framework-level mapping inconsistency — the attribute references a destination property that was renamed, removed, or misspelled. End users should not normally hit this unless running mismatched library versions.

Source

Thrown at libs/host/Configuration/Redis/RedisConfigSerializer.cs:198

        /// <param name="options">The Options object to populate</param>
        /// <returns>True if succeeded</returns>
        public static bool TryPopulateOptions(RedisOptions redisOptions, Options options)
        {
            foreach (var prop in GetProperties())
            {
                // Get source option value
                var srcOpt = prop.GetValue(redisOptions);

                // Ignore if source option is not set
                if (srcOpt == null) continue;

                // Get matching Options property defined by RedisOptionAttribute decorating RedisOption property
                var redisOptionAttr = (RedisOptionAttribute)prop.GetCustomAttributes(typeof(RedisOptionAttribute), false).First();
                var dstProp = typeof(Options).GetProperty(redisOptionAttr.GarnetOptionName);

                // Check if destination property exists
                if (dstProp == null)
                    throw new RedisSerializationException(
                        $"Unable to find property in {typeof(Options)} named {redisOptionAttr.GarnetOptionName} that matches {typeof(Options)} property {prop.Name}");

                // Get source option underlying value & type
                var srcOptValueProp = prop.PropertyType.GetProperty(nameof(Option<object>.Value));
                var srcOptValueType = prop.PropertyType.GenericTypeArguments.First();
                var srcOptValue = srcOptValueProp.GetValue(srcOpt);

                // Get destination property type
                var dstPropType = dstProp.PropertyType;

                // Try to convert source option to destination option
                object dstValue = null;

                // If custom transformer specified in RedisOptionAttribute, try to invoke transformer
                if (redisOptionAttr.GarnetCustomTransformer != null)
                {
                    var parameters = new[] { srcOptValue, null, null };
                    var result = (bool?)typeof(RedisConfigSerializer).GetMethod(nameof(TryApplyTransform), BindingFlags.NonPublic | BindingFlags.Static)

View on GitHub (pinned to 951b0fc683)

Solutions

  1. Ensure all assemblies (libs/host, libs/server) are from the same Garnet build/version.
  2. If you modified Options.cs property names, update every RedisOptionAttribute.GarnetOptionName that references the old name.
  3. Search the codebase for the GarnetOptionName value in the error to find the stale attribute.

Example fix

// before: Options.cs renamed 'Port' to 'ListenerPort'
//   but RedisOptions still has:
//   [RedisOption(Key = "port", GarnetOptionName = "Port")]

// after: update the attribute
//   [RedisOption(Key = "port", GarnetOptionName = "ListenerPort")]
Defensive patterns

Strategy: validation

Validate before calling

// Framework-level check: verify all RedisOptionAttribute.GarnetOptionName values exist on Options
foreach (var prop in typeof(RedisOptions).GetProperties()
    .Where(p => Attribute.IsDefined(p, typeof(RedisOptionAttribute))))
{
    var attr = (RedisOptionAttribute)prop.GetCustomAttributes(typeof(RedisOptionAttribute), false).First();
    if (typeof(Options).GetProperty(attr.GarnetOptionName) == null)
        throw new InvalidOperationException(
            $"RedisOptionAttribute on {prop.Name} references non-existent Options property '{attr.GarnetOptionName}'");
}

Prevention

When it happens

Trigger: Calling TryPopulateOptions with a set of RedisOptions whose attributes reference Options property names that no longer exist (e.g., after a refactor that renamed an Options property without updating the corresponding RedisOptionAttribute.GarnetOptionName).

Common situations: Running a Garnet build where libs/host Configuration/Options.cs was modified (property renamed/removed) but RedisOptions attributes were not updated; using a custom build with incomplete patches; version mismatch between assemblies.

Related errors


AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13). Data as JSON: /api/errors/89aca008137b6a3a. Report an issue: GitHub.