microsoft/garnet · critical · RedisSerializationException
Unable to convert property {prop.Name} in {typeof(RedisOptio
Error message
Unable to convert property {prop.Name} in {typeof(RedisOptions)} to property {redisOptionAttr.GarnetOptionName} in {typeof(Options)}. What it means
Thrown by RedisConfigSerializer.TryPopulateOptions when a RedisOptions property and its corresponding Options property have different types, no custom transformer is specified, and TryChangeType fails to convert between them. This indicates a type mapping gap in the framework's option-population logic.
Source
Thrown at libs/host/Configuration/Redis/RedisConfigSerializer.cs:231
if (redisOptionAttr.GarnetCustomTransformer != null)
{
var parameters = new[] { srcOptValue, null, null };
var result = (bool?)typeof(RedisConfigSerializer).GetMethod(nameof(TryApplyTransform), BindingFlags.NonPublic | BindingFlags.Static)
?.MakeGenericMethod(srcOptValueType, dstPropType, redisOptionAttr.GarnetCustomTransformer)
.Invoke(null, parameters);
dstValue = parameters[1];
if (!result.HasValue || !result.Value)
{
throw new RedisSerializationException((string)parameters[2]);
}
}
// Try to convert to destination type
else if (srcOptValueType != dstPropType)
{
if (!TryChangeType(srcOptValue, srcOptValueType, dstPropType, out dstValue))
{
throw new RedisSerializationException(
$"Unable to convert property {prop.Name} in {typeof(RedisOptions)} to property {redisOptionAttr.GarnetOptionName} in {typeof(Options)}.");
}
}
// Source and destination types are the same with no transformer specified
else
{
dstValue = srcOptValue;
}
// Set the destination property with the converted value
dstProp.SetValue(options, dstValue);
}
return true;
}
/// <summary>
/// Tries to apply a custom IGarnetCustomTransformer to transform a RedisOptions property to an Options propertyView on GitHub (pinned to 951b0fc683)
Solutions
- Add a GarnetCustomTransformer to the RedisOptionAttribute that handles the type conversion.
- Align the types of the RedisOptions property and Options property.
- Ensure all assemblies are from the same build to avoid type drift.
Example fix
// before: RedisOptions.Timeout is string, Options.Timeout is TimeSpan, no transformer
// after: add a transformer
// [RedisOption(Key = "timeout", GarnetOptionName = "Timeout",
// GarnetCustomTransformer = typeof(StringToTimeSpanTransformer))]
// public Option<string> Timeout { get; set; } Defensive patterns
Strategy: validation
Validate before calling
// Check type convertibility between RedisOptions and Options property types
var srcType = typeof(RedisOptions).GetProperty(propName).PropertyType.GenericTypeArguments.First();
var dstType = typeof(Options).GetProperty(dstPropName).PropertyType;
if (srcType != dstType)
{
var converter = TypeDescriptor.GetConverter(srcType);
if (!converter.CanConvertTo(dstType) && !TypeDescriptor.GetConverter(dstType).CanConvertFrom(srcType))
throw new InvalidOperationException($"No conversion path from {srcType.Name} to {dstType.Name} for {propName}");
} Prevention
- When property types differ between RedisOptions and Options, always provide a GarnetCustomTransformer.
- Add build-time tests that verify TryPopulateOptions succeeds for all mapped properties.
- Keep assembly versions aligned to avoid type drift.
When it happens
Trigger: During TryPopulateOptions, the source property type (from RedisOptions) and destination property type (from Options) differ, no GarnetCustomTransformer is set on the attribute, and the value cannot be converted via TypeDescriptor or Convert.ChangeType.
Common situations: Modifying a RedisOptions or Options property type without adding a custom transformer; framework version mismatch where a property type was changed in one assembly but not the other.
Related errors
- Unable to deserialize RedisOptions object. Unable to convert
- Unable to deserialize RedisOptions object. Unable to convert
- Unable to find property in {typeof(Options)} named {redisOpt
- Unable to deserialize RedisOptions object. Line {lineCount}
- Specified transformer for RedisOptions property does not mat
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/f4241b5b90cb0641.
Report an issue: GitHub.