microsoft/FASTER · error · FasterException
LogSettings.ObjectLogDevice needs to be specified (e.g.…
Error message
LogSettings.ObjectLogDevice needs to be specified (e.g., use Devices.CreateLogDevice, AzureStorageDevice, or NullDevice)
What it means
Thrown from the GenericAllocator constructor when the allocator supports non-blittable (object) keys/values but LogSettings.ObjectLogDevice was not set. Since keys or values live as managed objects, FASTER needs a separate object log device to persist them, distinct from the main LogDevice. Without it the allocator cannot be constructed at all, so it fails immediately at instance creation.
Solutions
- Set LogSettings.ObjectLogDevice = Devices.CreateLogDevice(path) for a dedicated object log file.
- If you do not want persistence, use LogSettings.ObjectLogDevice = new NullDevice() (and possibly a NullDevice for LogDevice too).
- Centralize device setup in one config factory so both LogDevice and ObjectLogDevice are always assigned for object-based KV types.
Example fix
// before
var logSettings = new LogSettings { LogDevice = Devices.CreateLogDevice("data.log") };
// after
var logSettings = new LogSettings
{
LogDevice = Devices.CreateLogDevice("data.log"),
ObjectLogDevice = Devices.CreateLogDevice("data.obj.log") // or new NullDevice()
}; Defensive patterns
Strategy: validation
Validate before calling
// Validate settings before constructing FASTER
if (settings.ObjectLogDevice == null)
settings.ObjectLogDevice = Devices.CreateLogDevice("data.obj.log", preallocateFile: false);
// or explicitly: settings.ObjectLogDevice = new NullDevice(); Type guard
static bool HasObjectLog(LogSettings s) => s.ObjectLogDevice != null;
Try / catch
try
{
var f = fkv.CreateNewInstance(storeSettings);
}
catch (FasterException ex) when (ex.Message.Contains("ObjectLogDevice"))
{
storeSettings.LogSettings.ObjectLogDevice = Devices.CreateLogDevice("data.obj.log", preallocateFile: false);
var f = fkv.CreateNewInstance(storeSettings);
} Prevention
- Use a single settings-factory that always sets both LogDevice and ObjectLogDevice for object-typed KV pairs.
- Add a startup assertion that ObjectLogDevice != null when typeof(Key) or typeof(Value) contains reference types.
- When only testing in memory, explicitly use NullDevice for both devices rather than leaving fields null.
When it happens
Trigger: Creating a FASTER instance (f(kv, ...) with class/struct key or value types containing object references) via CreateKVSettings/LogSettings where LogDevice is set but ObjectLogDevice is left null, with LogDevice not a NullDevice.
Common situations: Using class-type keys/values without calling Devices.CreateLogDevice for a second device; copying blittable-only sample config to an object-based workload; forgetting NullDevice.Instance when no persistence is wanted.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Objects in key/value, but object log not provided during…
- Object log device should not have fixed segment size. Set…
- LogSettings.LogDevice needs to be specified (e.g., use…
- Segment ( ) must be at least of page size ( )
- Memory size ( ) must be configured to be either 1 (i.e., 0…
AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15).
Data as JSON: /api/errors/99fabc8247e15c9b.
Report an issue: GitHub.
Appendix: source
Thrown at cs/src/core/Allocator/GenericAllocator.cs:52
// Tail offsets per segment, in object log
public readonly long[] segmentOffsets;
// Record sizes
private static readonly int recordSize = Unsafe.SizeOf<Record<Key, Value>>();
private readonly SerializerSettings<Key, Value> SerializerSettings;
private readonly bool keyBlittable = Utility.IsBlittable<Key>();
private readonly bool valueBlittable = Utility.IsBlittable<Value>();
private readonly OverflowPool<Record<Key, Value>[]> overflowPagePool;
public GenericAllocator(LogSettings settings, SerializerSettings<Key, Value> serializerSettings, IFasterEqualityComparer<Key> comparer,
Action<long, long> evictCallback = null, LightEpoch epoch = null, Action<CommitInfo> flushCallback = null, ILogger logger = null)
: base(settings, comparer, evictCallback, epoch, flushCallback, logger)
{
overflowPagePool = new OverflowPool<Record<Key, Value>[]>(4);
if (settings.ObjectLogDevice == null)
{
throw new FasterException("LogSettings.ObjectLogDevice needs to be specified (e.g., use Devices.CreateLogDevice, AzureStorageDevice, or NullDevice)");
}
SerializerSettings = serializerSettings ?? new SerializerSettings<Key, Value>();
if ((!keyBlittable) && (settings.LogDevice as NullDevice == null) && ((SerializerSettings == null) || (SerializerSettings.keySerializer == null)))
{
#if DEBUG
if (typeof(Key) != typeof(byte[]) && typeof(Key) != typeof(string))
Debug.WriteLine("Key is not blittable, but no serializer specified via SerializerSettings. Using (slow) DataContractSerializer as default.");
#endif
SerializerSettings.keySerializer = ObjectSerializer.Get<Key>();
}
if ((!valueBlittable) && (settings.LogDevice as NullDevice == null) && ((SerializerSettings == null) || (SerializerSettings.valueSerializer == null)))
{
#if DEBUG
if (typeof(Value) != typeof(byte[]) && typeof(Value) != typeof(string))
Debug.WriteLine("Value is not blittable, but no serializer specified via SerializerSettings. Using (slow) DataContractSerializer as default.");View on GitHub (pinned to 321d872eab)