{"record":{"id":"53c58aef34dfa19b","repo":"microsoft/garnet","slug":"malformed-acl-rule","errorCode":null,"errorMessage":"Malformed ACL rule","messagePattern":"Malformed ACL rule","errorType":"validation","errorClass":"ACLParsingException","httpStatus":null,"severity":"error","filePath":"libs/server/ACL/ACLParser.cs","lineNumber":88,"sourceCode":"        ///     !&lt;hash>: Remove the password hash from the list of valid passwords for the user\n        ///     nopass: Specify this user can login without a password.\n        ///     resetpass: Reset all passwords defined for the user so far and disable passwordless login.\n        /// </summary>\n        /// <param name=\"input\">A single line Redis-style ACL rule.</param>\n        /// <param name=\"acl\">An optional access control list to modify.</param>\n        /// <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)","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/server/ACL/ACLParser.cs#L70-L106","documentation":"Thrown by ACLParser.ParseACLRule when the tokenized input has fewer than 3 tokens. A well-formed ACL rule is 'user <username> <op>...' — at minimum three whitespace-separated tokens. Fewer means the line is too short to be a valid rule. It is an ACLParsingException carrying filename and line number context when reached via file import.","triggerScenarios":"Passing a line like 'user' (1 token) or 'user alice' (2 tokens, no operation), or an empty/whitespace-only string after trim that somehow split to < 3 tokens; a config file line missing the operation clause.","commonSituations":"Hand-edited ACL config files with a truncated rule; a copy-paste that dropped the operations; a line that used a different delimiter (e.g. comma) instead of whitespace so it did not split into 3.","solutions":["Ensure each ACL rule line has at least: 'user <name> <one-op>'.","Use whitespace (space/tab) between tokens, not commas.","Validate the rule with a pre-flight tokenizer that asserts >= 3 tokens before parsing.","When loading from file, the Import loop wraps this in an ACLParsingException with file:line for easy location."],"exampleFix":"// before\nACLParser.ParseACLRule(\"user alice\");\n\n// after\nACLParser.ParseACLRule(\"user alice on >password\");","handlingStrategy":"validation","validationCode":"var tokens = input.Trim().Split(new[]{' ','\\t','\\r','\\n'}, StringSplitOptions.RemoveEmptyEntries);\nif (tokens.Length < 3) throw new ArgumentException(\"ACL rule needs >= 3 tokens: user <name> <op>\");","typeGuard":"static bool IsWellFormedRule(string input) =>\n    input.Trim().Split(new[]{' ','\\t','\\r','\\n'}, StringSplitOptions.RemoveEmptyEntries).Length >= 3;","tryCatchPattern":"try { ACLParser.ParseACLRule(line, acl); }\ncatch (ACLParsingException ex) { logger.LogError(\"Bad ACL line {File}:{Line}: {Msg}\", ex.Filename, ex.Line, ex.Message); }","preventionTips":["Lint ACL files with a token-count check before load.","Use whitespace delimiters, not commas.","Ensure each rule has at least one operation clause."],"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"}