microsoft/garnet · critical · InvalidOperationException
Failed to create BfTree instance.
Error message
Failed to create BfTree instance.
What it means
Thrown by the BfTreeService constructor when the native bftree_create function returns a null pointer (0). This means the native BfTree library failed to allocate or initialize the tree structure. Possible causes include out-of-memory conditions, invalid parameters (e.g., zero page sizes, impossible record size constraints), file I/O errors when opening the disk path, or missing native library dependencies.
Source
Thrown at libs/native/bftree-garnet/BfTreeService.cs:172
uint cbMaxRecordSize = 0,
uint cbMaxKeyLen = 0,
uint leafPageSize = 0)
{
_storageBackend = storageBackend;
_filePath = filePath;
if (storageBackend == StorageBackendType.Disk && string.IsNullOrEmpty(filePath))
throw new ArgumentException("filePath is required for disk-backed trees.", nameof(filePath));
byte[] pathBytes = filePath != null ? Encoding.UTF8.GetBytes(filePath) : null;
byte useSnapshot = (byte)(enableSnapshots ? 1 : 0);
fixed (byte* pp = pathBytes)
{
_tree = NativeBfTreeMethods.bftree_create(
cbSizeByte, cbMinRecordSize, cbMaxRecordSize, cbMaxKeyLen, leafPageSize,
(byte)storageBackend, pp, pathBytes?.Length ?? 0,
useSnapshot);
}
if (_tree == 0)
throw new InvalidOperationException("Failed to create BfTree instance.");
}
/// <summary>
/// Creates a BfTreeService wrapping an existing native tree pointer (e.g. from snapshot restore).
/// Takes ownership of the pointer.
/// </summary>
internal BfTreeService(nint treePtr, StorageBackendType storageBackend, string filePath = null)
{
if (treePtr == 0)
throw new ArgumentException("Tree pointer must not be null.", nameof(treePtr));
_tree = treePtr;
_storageBackend = storageBackend;
_filePath = filePath;
}
// ---------------------------------------------------------------
// Point operations — PinnedSpanByte (zero-overhead for Garnet hot paths)
// ---------------------------------------------------------------View on GitHub (pinned to 951b0fc683)
Solutions
- Verify the filePath directory exists and is writable (for disk backend).
- Check that cbSizeByte, cbMinRecordSize, cbMaxRecordSize, and leafPageSize are valid non-zero values.
- Ensure sufficient memory is available in the container/host environment.
- Verify the native BfTree library is loaded and matches the process architecture (x64/x86).
- Check native library logs or stderr for additional error detail from bftree_create.
Example fix
// before: zero size params and nonexistent path
var svc = new BfTreeService(
storageBackend: StorageBackendType.Disk,
filePath: "/nonexistent/path/tree.dat",
cbSizeByte: 0,
leafPageSize: 0
);
// after: valid params and existing directory
Directory.CreateDirectory("/var/lib/garnet");
var svc = new BfTreeService(
storageBackend: StorageBackendType.Disk,
filePath: "/var/lib/garnet/tree.dat",
cbSizeByte: 1024 * 1024 * 100,
leafPageSize: 4096
); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate parameters before construction
if (storageBackend == StorageBackendType.Disk)
{
var dir = Path.GetDirectoryName(filePath);
if (!Directory.Exists(dir))
throw new DirectoryNotFoundException($"BfTree directory does not exist: {dir}");
}
if (cbSizeByte == 0) throw new ArgumentException("cbSizeByte must be non-zero.", nameof(cbSizeByte));
if (leafPageSize == 0) throw new ArgumentException("leafPageSize must be non-zero.", nameof(leafPageSize)); Try / catch
try
{
var svc = new BfTreeService(storageBackend, filePath, enableSnapshots, cbSizeByte,
cbMinRecordSize, cbMaxRecordSize, cbMaxKeyLen, leafPageSize);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Failed to create BfTree"))
{
logger.LogError(ex, "Native BfTree creation failed. Check memory, path permissions, and parameters.");
throw;
} Prevention
- Verify the file path directory exists and is writable before creating a disk-backed tree.
- Provide non-zero, reasonable values for cbSizeByte and leafPageSize.
- Ensure the native BfTree library matches the process architecture.
- Monitor available memory in containers to avoid allocation failures.
When it happens
Trigger: Calling the BfTreeService constructor where the native bftree_create P/Invoke returns 0. This can happen with invalid sizing parameters, insufficient memory, file permission issues on the disk path, or a corrupted/missing native library.
Common situations: Running in memory-constrained containers; providing invalid size parameters (cbSizeByte=0 with unreasonable min/max record sizes); file path pointing to a directory that doesn't exist or lacks write permissions; native library not loaded or incompatible architecture.
Related errors
- filePath is required for disk-backed trees.
- bftree_scan_with_count returned a null handle.
- bftree_scan_with_end_key returned a null handle.
- Native handle is null.
- Snapshot path is required.
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/504166d9121a693f.
Report an issue: GitHub.