microsoft/garnet · error · ACLException

Unknown custom command '{name}' (not registered with any loa

Error message

Unknown custom command '{name}' (not registered with any loaded module)

What it means

Thrown during ACL SETUSER (the retry-loop that applies ACL ops) when a newly-added entry in the user's CustomCommandsAllowed set does not match any registered custom command. The check is intentionally limited to names not already present in the pre-op allow/deny sets (so toggling legacy names does not false-positive), so it fires specifically for freshly-introduced, unregistered names - almost always a typo or a missing module.

Source

Thrown at libs/server/Resp/ACLCommands.cs:214

                    for (var i = 1; i < ops.Length; i++)
                    {
                        ACLParser.ApplyACLOpToUser(ref newUser, ops[i]);
                    }

                    // At SETUSER time modules are loaded; any newly-added per-name custom permission
                    // must resolve against CustomCommandManager. Unknown names here are almost always
                    // typos - fail closed.
                    var ccm = storeWrapper.customCommandManager;
                    if (ccm != null)
                    {
                        foreach (var name in newUser.CustomCommandsAllowed)
                        {
                            // A name already present in either pre-op set (allow/deny) is not "new" from
                            // the system's POV - only flag names absent from both presets and unregistered.
                            // This permits toggling (allow↔deny) of loose-loaded names without false-positive throws.
                            if (!preAllowed.Contains(name) && !preDenied.Contains(name) && !ccm.IsCustomCommandRegistered(name))
                            {
                                throw new ACLException($"Unknown custom command '{name}' (not registered with any loaded module)");
                            }
                        }
                        foreach (var name in newUser.CustomCommandsDenied)
                        {
                            if (!preAllowed.Contains(name) && !preDenied.Contains(name) && !ccm.IsCustomCommandRegistered(name))
                            {
                                throw new ACLException($"Unknown custom command '{name}' (not registered with any loaded module)");
                            }
                        }
                    }
                }
                while (!userHandle.TrySetUser(newUser, currentUser));
            }
            catch (ACLException exception)
            {
                // Abort command execution
                while (!RespWriteUtils.TryWriteError($"ERR {exception.Message}", ref dcurr, dend))
                    SendAndReset();

View on GitHub (pinned to 951b0fc683)

Solutions

  1. Correct the command name in the ACL rule to match the registered custom command exactly (case-sensitive).
  2. Ensure the module that registers the custom command is loaded before applying the ACL rule.
  3. List registered custom commands (e.g., via COMMAND DOCS / module introspection) to confirm the exact name.

Example fix

# before
ACL SETUSER alice on >pass +mycuston   # typo: should be mycustom
# after
ACL SETUSER alice on >pass +mycustom
Defensive patterns

Strategy: validation

Validate before calling

// Before issuing ACL SETUSER with custom command rules
foreach (var name in allowCustomNames) {
    if (!storeWrapper.customCommandManager.IsCustomCommandRegistered(name))
        throw new InvalidOperationException($"Refusing ACL rule: custom command '{name}' is not registered.");
}

Try / catch

catch (ACLException ex) when (ex.Message.Contains("Unknown custom command")) {
    // ACL rule referenced an unregistered name; surface to operator, do not persist the user change
    logger.LogWarning("ACL SETUSER rejected: {Msg}", ex.Message);
}

Prevention

When it happens

Trigger: An ACL SETUSER rule adds a +<customname> allow entry where <customname> is not registered with CustomCommandManager and was not already in the user's allow/deny sets.

Common situations: Typing a custom command name wrong in an ACL rule; referencing a custom command from a module that is not loaded; applying an ACL file before the module defining the command has loaded (for names not already preset).

Related errors


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