microsoft/FASTER · error · Exception
Cannot use BlittableParameterSerializer with non-blittable…
Error message
Cannot use BlittableParameterSerializer with non-blittable types - specify serializer explicitly
What it means
FixedLenSerializer's static constructor validates at type-initialization time that Key, Value, Input and Output are all blittable (contain no references and have identical managed/native layout). FASTER's FixedLen/BlittableParameterSerializer path memcpy's raw bytes and can only work with unmanaged, blittable types; using it with e.g. string or a struct containing references would corrupt data, so it throws during static init (as TypeInitializationException).
Solutions
- Use blittable types (long, int, fixed-size structs with only primitives) for Key/Value/Input/Output.
- For non-blittable types, specify an explicit ISerializer implementation (e.g. a var-length or custom serializer) instead of FixedLenSerializer.
- If using a struct with reference fields, switch to byte arrays/fixed buffers or a varlen serializer path (e.g. VarLenSerializer or MemorySerializer).
Example fix
// before using var session = store.For(...).NewSession<FixedLenSerializer<long, string, long, string>>(); // after using var session = store.For(...).NewSession<VarLenSerializer<long, string, long, string>>(); // or use fixed-size struct for Value
Defensive patterns
Strategy: type-guard
Validate before calling
static bool IsBlittable<T>() => !(typeof(T).IsArray || typeof(T) == typeof(string) || typeof(T).IsClass) && (typeof(T).IsValueType && !typeof(T).IsGenericType && typeof(T).GetFields().All(f => f.FieldType == typeof(T) || f.FieldType.IsPrimitive || IsBlittable(f.FieldType)));
Type guard
static bool CanUseFixedLen<K,V,I,O>() => IsBlittable<K>() && IsBlittable<V>() && IsBlittable<I>() && IsBlittable<O>();
Try / catch
try { Activator.CreateInstance(typeof(FixedLenSerializer<K,V,I,O>)); } catch (TypeInitializationException ex) { /* select explicit serializer instead */ } Prevention
- Restrict FixedLenSerializer to primitives and structs of primitives only.
- For strings or reference-bearing structs, always choose VarLenSerializer or a custom ISerializer up front.
When it happens
Trigger: Declaring FixedLenSerializer<...> (or FASTER's blittable parameter serializer) with any generic type argument that is non-blittable — e.g. string, object, a struct with a string/object field — which fires the static constructor on first use.
Common situations: Using string keys/values with the fixed-length serializer for convenience; defining a record struct containing a reference-type field and assuming it is blittable; upgrading FASTER versions where serializer selection became stricter.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- AsyncReadRecordObjectsToMemory invalid for…
- BlittableAllocator memory pages are sector aligned - use…
- Out of order message within session
- Unexpected status of SubscribeKV
- Cannot use BlittableParameterSerializer with non-blittable…
AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15).
Data as JSON: /api/errors/3ef199e176999bc7.
Report an issue: GitHub.
Appendix: source
Thrown at cs/remote/src/FASTER.server/FixedLenSerializer.cs:27
namespace FASTER.server
{
/// <summary>
/// Server-side serializer for blittable types
/// </summary>
/// <typeparam name="Key">Key</typeparam>
/// <typeparam name="Value">Value</typeparam>
/// <typeparam name="Input">Input</typeparam>
/// <typeparam name="Output">Output</typeparam>
public unsafe struct FixedLenSerializer<Key, Value, Input, Output> : IServerSerializer<Key, Value, Input, Output>
where Key : unmanaged
where Value : unmanaged
where Input : unmanaged
where Output : unmanaged
{
static FixedLenSerializer()
{
if (!IsBlittable<Key>() || !IsBlittable<Value>() || !IsBlittable<Input>() || !IsBlittable<Output>())
throw new Exception("Cannot use BlittableParameterSerializer with non-blittable types - specify serializer explicitly");
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref Key ReadKeyByRef(ref byte* src)
{
var _src = (void*)src;
src += Unsafe.SizeOf<Key>();
return ref Unsafe.AsRef<Key>(_src);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref Value ReadValueByRef(ref byte* src)
{
var _src = (void*)src;
src += Unsafe.SizeOf<Value>();
return ref Unsafe.AsRef<Value>(_src);View on GitHub (pinned to 321d872eab)