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

  1. Use blittable types (long, int, fixed-size structs with only primitives) for Key/Value/Input/Output.
  2. For non-blittable types, specify an explicit ISerializer implementation (e.g. a var-length or custom serializer) instead of FixedLenSerializer.
  3. 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

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


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)