microsoft/garnet · error · RedisSerializationException
Unable to deserialize RedisOptions object. Unable to convert
Error message
Unable to deserialize RedisOptions object. Unable to convert object of type {typeof(string)} to object of type {optType}. (Line: {lineCount}; Key: {key}; Property: {prop.Name}). What it means
Thrown by RedisConfigSerializer.Deserialize when a non-array option value cannot be converted from string to the option's underlying type. This is the fallback after TryChangeType fails for scalar options — e.g., providing 'abc' for an integer property. The parser tried TypeDescriptor converters and Convert.ChangeType, all of which failed.
Source
Thrown at libs/host/Configuration/Redis/RedisConfigSerializer.cs:120
// Instantiate a new array
var elemType = optType.GetElementType();
newVal = Array.CreateInstance(elemType, values.Length);
// Try deserializing and setting array elements
for (var i = 0; i < values.Length; i++)
{
if (!TryChangeType(values[i], typeof(string), elemType, out var elem))
throw new RedisSerializationException(
$"Unable to deserialize {nameof(RedisOptions)} object. Unable to convert object of type {typeof(string)} to object of type {elemType}. (Line: {lineCount}; Key: {key}; Property: {prop.Name}).");
((Array)newVal).SetValue(elem, i);
}
}
else
{
throw new RedisSerializationException(
$"Unable to deserialize {nameof(RedisOptions)} object. Unable to convert object of type {typeof(string)} to object of type {optType}. (Line: {lineCount}; Key: {key}; Property: {prop.Name}).");
}
}
// Create a new Option<T> object
var newOpt = Activator.CreateInstance(prop.PropertyType);
// Set the underlying option value
var valueProp = prop.PropertyType.GetProperty(nameof(Option<object>.Value));
valueProp.SetValue(newOpt, newVal);
// Set the options property to the new option object
prop.SetValue(options, newOpt);
// Append usage warning, if defined
var redisOptionAttr = (RedisOptionAttribute)prop.GetCustomAttributes(typeof(RedisOptionAttribute), false).First();
if (!string.IsNullOrEmpty(redisOptionAttr.UsageWarning))
{View on GitHub (pinned to 951b0fc683)
Solutions
- Check the property name and key in the error message to identify the directive.
- Provide a value that matches the expected type (e.g., integer for Port, valid boolean or numeric for timeout).
- Refer to the GarnetServerOptions property type for the correct value format.
Example fix
// before: // port abc // after: // port 6379
Defensive patterns
Strategy: validation
Validate before calling
var propType = typeof(RedisOptions).GetProperty(key)?.PropertyType;
if (propType != null)
{
var optType = propType.GenericTypeArguments.First();
var converter = TypeDescriptor.GetConverter(optType);
if (!converter.IsValid(value))
throw new FormatException($"Value '{value}' is not valid for type {optType.Name} (key: {key})");
} Type guard
static bool CanConvertScalar(string value, Type targetType)
{
var converter = TypeDescriptor.GetConverter(targetType);
return converter.IsValid(value);
} Try / catch
try
{
var redisOpts = RedisConfigSerializer.Deserialize(reader, logger);
}
catch (RedisSerializationException ex) when (ex.Message.Contains("Unable to convert object of type"))
{
logger.LogError("Redis config value type mismatch: {msg}", ex.Message);
throw;
} Prevention
- Match config values to the expected property types (int, string, bool, etc.).
- Pre-validate values using TypeDescriptor before loading config.
- Document the expected type for each directive in config templates.
When it happens
Trigger: A config directive whose value is a single scalar that doesn't match the property type. For example, 'port abc' where Port expects an int, or 'timeout true' where the property expects a numeric value.
Common situations: Typographical errors in config files; unit mismatches (e.g., providing '10ms' where a raw integer is expected); locale-related number format issues; using a Redis directive name that maps to a different type than expected.
Related errors
- Unable to deserialize RedisOptions object. Unable to convert
- Unable to deserialize RedisOptions object. Line {lineCount}
- Unable to convert property {prop.Name} in {typeof(RedisOptio
- Expected start of JSON object.
- Unable to find property in {typeof(Options)} named {redisOpt
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/9a05b57a187461ec.
Report an issue: GitHub.