microsoft/garnet · error · GarnetException

Could not run function preamble: {errMsg}

Error message

Could not run function preamble: {errMsg}

What it means

Thrown when executing a registered function (e.g., FCALL) and the function's preamble - the code that registers declared keys and argv into the sandbox - fails its protected call. errMsg is the Lua error from the stack (or 'No error provided' if the stack was empty). The preamble is built by Garnet from the function's key_specs, so a failure usually means a malformed function registration or a bad key declaration.

Source

Thrown at libs/server/Lua/LuaRunner.cs:1226

                    preambleArgv = argv;

                    state.PushCFunction(&LuaRunnerTrampolines.RunPreambleForRunner);
                    var preambleRes = state.PCall(0, 0);
                    if (preambleRes != LuaStatus.OK || state.StackTop != 0)
                    {
                        string errMsg;
                        if (state.StackTop >= 1 && state.Type(1) == LuaType.String)
                        {
                            // We control the definition of LoaderBlock, so we know this is a string
                            state.KnownStringToBuffer(1, out var preambleErrSpan);
                            errMsg = Encoding.UTF8.GetString(preambleErrSpan);
                        }
                        else
                        {
                            errMsg = "No error provided";
                        }

                        throw new GarnetException($"Could not run function preamble: {errMsg}");
                    }
                }
                finally
                {
                    preambleKeys = preambleArgv = null;
                }

                RunnerAdapter adapter;
                if (txnMode && keys?.Length > 0)
                {
                    // Add keys to the transaction
                    foreach (var key in keys)
                    {
                        var _key = scratchBufferBuilder.CreateArgSlice(key);
                        txnKeyEntries.AddKey(_key, Tsavorite.core.LockType.Exclusive);
                        scratchBufferBuilder.RewindScratchBuffer(_key);
                    }

View on GitHub (pinned to 951b0fc683)

Solutions

  1. Re-examine the function's key-count/key declaration at registration time.
  2. Read errMsg for the Lua-side cause.
  3. Reload the function with corrected metadata.

Example fix

-- before (Lua) - wrong key count declared
redis.register_function { function_name='f', key_count=5, callback=cb }  -- only passes 2 keys
-- after
redis.register_function { function_name='f', key_count=2, callback=cb }
Defensive patterns

Strategy: try-catch

Try / catch

try {
    result = server.FCall("f", keys, argv);
} catch (GarnetException ex) when (ex.Message.StartsWith("Could not run function preamble")) {
    logger.LogError("Function preamble failed: {Msg}", ex.Message);
    return ServiceUnavailable(ex.Message);
}

Prevention

When it happens

Trigger: An FCALL/FCALL_RO invocation runs state.PushCFunction(RunPreambleForRunner) then PCall; it returns non-OK or leaves items on the stack, so the preamble did not complete cleanly.

Common situations: A function declared with an invalid number-of-keys spec; a function whose preamble references a removed/disallowed API; mismatch between registered function metadata and the runtime.

Related errors


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