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.

Solutions

  1. Verify the filePath directory exists and is writable (for disk backend).
  2. Check that cbSizeByte, cbMinRecordSize, cbMaxRecordSize, and leafPageSize are valid non-zero values.
  3. Ensure sufficient memory is available in the container/host environment.
  4. Verify the native BfTree library is loaded and matches the process architecture (x64/x86).
  5. 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

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


AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13). Data as JSON: /api/errors/504166d9121a693f. Report an issue: GitHub.

Appendix: 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)