microsoft/garnet · error · GarnetException
ACL strict mode: {unresolved.Count} unresolved (user, custom
Error message
ACL strict mode: {unresolved.Count} unresolved (user, custom-command) entries in ACL rules: {entries}. Disable acl-strict-custom-commands or load the appropriate module(s). What it means
Thrown during GarnetServer initialization when ACL strict mode (opts.AclStrictCustomCommands) is enabled and one or more ACL rules reference custom commands that are not registered with any loaded module. The strict mode is a fail-closed safety mechanism: it prevents operators from shipping ACL configurations with typos that would silently deny commands. The error lists the specific unresolved user-command pairs.
Source
Thrown at libs/host/GarnetServer.cs:360
}
}
if (unresolved.Count == 0)
{
return;
}
foreach (var (user, name) in unresolved)
{
logger?.LogWarning("ACL rule references custom command '{name}' for user '{user}' which is not registered with any loaded module", name, user);
}
if (opts.AclStrictCustomCommands)
{
// Strict mode: fail closed so operators can't accidentally ship an ACL with typos
// that would silently match no command (and therefore deny by default at dispatch).
var entries = string.Join(", ", unresolved.Select(t => $"({t.user},{t.name})"));
throw new GarnetException($"ACL strict mode: {unresolved.Count} unresolved (user, custom-command) entries in ACL rules: {entries}. Disable acl-strict-custom-commands or load the appropriate module(s).");
}
}
private GarnetDatabase CreateDatabase(int dbId, GarnetServerOptions serverOptions, ClusterFactory clusterFactory,
CustomCommandManager customCommandManager)
{
var removeOutdated = !serverOptions.EnableCluster;
// Two-roots layout for RangeIndex files:
// riLogRoot — log-tied (working file + per-flush snapshots), co-located with hlog.
// Falls back through LogDir → CheckpointDir → cwd, mirroring Tsavorite's
// CheckpointBaseDirectory chain so RangeIndex works without storage tier.
// cprDir — checkpoint-tied (per-token snapshots live under <token>/rangeindex/),
// alongside Tsavorite's cpr-checkpoints/<token>/info.dat etc.
// Construct the manager only when the feature is enabled. When disabled, the
// store wrapper / triggers / functions hold a null reference, and Tsavorite's
// record-trigger gates (CallOnFlush etc.) return false → zero per-op overhead.
RangeIndexManager rangeIndexManager = null;
if (serverOptions.EnableRangeIndexPreview)View on GitHub (pinned to 951b0fc683)
Solutions
- Load the appropriate module(s) that register the referenced custom commands before the ACL is validated.
- Fix typos in the ACL file — the error message lists the specific (user, command) pairs.
- If you intentionally want to ship ACLs with not-yet-loaded commands, set AclStrictCustomCommands=false (but note this weakens the safety check).
- Verify that module command registration names exactly match the names used in ACL rules.
Example fix
// before: ACL references 'MYCMD' but module not loaded // user alice on >password ~* +MYCMD // after: load module first or fix command name // garnet-server --loadmodule ./mymodule.so // user alice on >password ~* +MYCMD
Defensive patterns
Strategy: validation
Validate before calling
// Before strict validation, verify all ACL-referenced custom commands are registered
foreach (var user in aclUsers)
{
foreach (var cmd in user.CustomCommandsAllowed.Concat(user.CustomCommandsDenied))
{
if (!customCommandManager.IsCustomCommandRegistered(cmd))
throw new InvalidOperationException(
$"ACL references unregistered custom command '{cmd}' for user '{user.Name}'. Load the module first.");
}
} Try / catch
try
{
server = new GarnetServer(commandLineArgs, loggerFactory);
}
catch (GarnetException ex) when (ex.Message.Contains("ACL strict mode"))
{
logger.LogError(ex, "ACL references unresolved custom commands. Load modules or disable acl-strict-custom-commands.");
throw;
} Prevention
- Load all modules before the ACL is validated at startup.
- Ensure ACL command names exactly match module registration names.
- Set AclStrictCustomCommands=false in development when iterating on modules (re-enable for production).
- Audit ACL files against loaded modules during CI.
When it happens
Trigger: An ACL configuration grants or denies a custom command (via CustomCommandsAllowed or CustomCommandsDenied) for a user, but no loaded Garnet module has registered that command name. With AclStrictCustomCommands=true, this is treated as a fatal startup error.
Common situations: Deploying an ACL file that references module commands before loading the module; typos in custom command names in the ACL file; upgrading a module that renamed or removed a command without updating the ACL; developing custom modules where the command registration name differs from the ACL rule.
Related errors
- Unable to parse ACL rule {exception.Filename}:{exception.Lin
- Unknown custom command '{name}' (not registered with any loa
- Gossip sample fraction should be in range [0,100]
- Cannot use AzureStorage device without supplying storage-str
- Cannot use AzureStorage device with both storage-string and
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/886c0fb024aeaebe.
Report an issue: GitHub.