{"record":{"id":"ff2b3873c08b1491","repo":"microsoft/garnet","slug":"acl-rules-need-to-start-with-the-user-keyword","errorCode":null,"errorMessage":"ACL rules need to start with the USER keyword","messagePattern":"ACL rules need to start with the USER keyword","errorType":"validation","errorClass":"ACLParsingException","httpStatus":null,"severity":"error","filePath":"libs/server/ACL/ACLParser.cs","lineNumber":94,"sourceCode":"        /// <returns>A user object representing the modified user.</returns>\n        /// <exception cref=\"ACLParsingException\">Thrown if the ACL rule cannot be parsed.</exception>\n        /// <exception cref=\"ACLCategoryDoesNotExistException\">Thrown if the ACL command category used by the operation does not exist.</exception>\n        /// <exception cref=\"ACLUnknownOperationException\">Thrown if the given operation does not exist.</exception>\n        public static User ParseACLRule(string input, AccessControlList acl = null)\n        {\n            // Tokenize input string \n            string[] tokens = input.Trim().Split(WhitespaceChars, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);\n\n            // Sanity check for correctness\n            if (tokens.Length < 3)\n            {\n                throw new ACLParsingException(\"Malformed ACL rule\");\n            }\n\n            // Expect keyword USER\n            if (!tokens[0].Equals(\"user\", StringComparison.OrdinalIgnoreCase))\n            {\n                throw new ACLParsingException(\"ACL rules need to start with the USER keyword\");\n            }\n\n            // Expect username\n            string username = tokens[1];\n\n            // Retrieve/add the user with the username to the access control list, if provided\n            User user;\n            if (acl != null)\n            {\n                user = acl.GetUserHandle(username)?.User;\n\n                if (user == null)\n                {\n                    user = new User(username);\n                    acl.AddUserHandle(new UserHandle(user));\n                }\n            }\n            else","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/server/ACL/ACLParser.cs#L76-L112","documentation":"Thrown by ACLParser.ParseACLRule when the first token is not 'user' (case-insensitive). The Redis/Garnet ACL rule grammar requires every rule to begin with the USER keyword. Any other leading token (typo, wrong command, stray character) is rejected as ACLParsingException.","triggerScenarios":"Passing a line whose first token is 'User-', 'users', 'usr', 'acl', or any non-'user' string. Also a line that begins with an operation like 'on' or a username directly.","commonSituations":"Mistyping the keyword; pasting a Redis CONFIG rewrite line into an ACL file; a line that is actually a comment but lacks the leading '#' (comments are skipped earlier in Import, but ParseACLRule itself does not skip them).","solutions":["Start every ACL rule line with the literal token 'user' (case-insensitive).","Prefix genuine comments with '#' so Import skips them.","Run a config linter that asserts tokens[0].Equals(\"user\", OrdinalIgnoreCase).","Double-check for invisible leading characters (BOM, spaces are trimmed but stray tabs mid-token are not)."],"exampleFix":"// before\nACLParser.ParseACLRule(\"alice on >pass\");\n\n// after\nACLParser.ParseACLRule(\"user alice on >pass\");","handlingStrategy":"validation","validationCode":"var tokens = input.Trim().Split();\nif (tokens.Length == 0 || !tokens[0].Equals(\"user\", StringComparison.OrdinalIgnoreCase))\n    throw new ArgumentException(\"ACL rule must start with 'user'\");","typeGuard":"static bool StartsUserKeyword(string input) =>\n    input.Trim().StartsWith(\"user\", StringComparison.OrdinalIgnoreCase);","tryCatchPattern":"try { ACLParser.ParseACLRule(line, acl); }\ncatch (ACLParsingException ex) { /* report file:line */ }","preventionTips":["Always begin ACL rule lines with 'user'.","Prefix comments with '#'.","Run a config linter that asserts the leading token."],"tags":["acl","parsing","configuration","validation"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}