{"record":{"id":"7e22d5d83b76a02d","repo":"gravitational/teleport","slug":"want-or-found-q-s","errorCode":null,"errorMessage":"want '+' or ',', found %q: %s","messagePattern":"want '\\+' or ',', found %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/utils/pkixname/parser.go","lineNumber":566,"sourceCode":"\t\t\t}\n\n\t\tcase tokenizeStateStringQuote:\n\t\t\tswitch r {\n\t\t\tcase '\\\\':\n\t\t\t\tescapeStart()\n\t\t\tcase '\"':\n\t\t\t\temitBuffer(tokenString)\n\t\t\t\tstate = tokenizeStateStringQuoteEnd\n\t\t\tdefault:\n\t\t\t\tbuf.WriteRune(r)\n\t\t\t}\n\n\t\tcase tokenizeStateStringQuoteEnd:\n\t\t\tswitch r {\n\t\t\tcase '+', ',', ';':\n\t\t\t\ttransitionToNameComponent(r)\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"want '+' or ',', found %q: %s\", r, errTrace(pos))\n\t\t\t}\n\t\t}\n\t}\n\n\t// Input ended, check the final state.\n\tswitch state {\n\tcase tokenizeStateInit:\n\t\t// OK.\n\tcase tokenizeStateNameComponent:\n\t\treturn nil, fmt.Errorf(\"want attributeType, found EOF\")\n\tcase tokenizeStateAttrType:\n\t\treturn nil, fmt.Errorf(\"want attributeType or '=', found EOF\")\n\tcase tokenizeStateAttrTypeEnd:\n\t\treturn nil, fmt.Errorf(\"want '=' attributeValue, found EOF\")\n\tcase tokenizeStateStringStart, tokenizeStateString, tokenizeStateStringEnd:\n\t\t// OK.\n\t\temitBuffer(tokenString)\n\tcase tokenizeStateStringEscape:","sourceCodeStart":548,"sourceCodeEnd":584,"githubUrl":"https://github.com/gravitational/teleport/blob/1283425b60ec5f60d509ba4c791183d452923ff7/api/utils/pkixname/parser.go#L548-L584","documentation":"After a closing quote of a quoted attribute value, the tokenizer only accepts a '+' (multi-valued RDN) or ','/' ;' (next RDN). Any other character after the quoted string is rejected. Whitespace is skipped before this check, so the error means real stray content follows the quoted value.","triggerScenarios":"Calling ParseDistinguishedName with content after a quoted value, e.g. \"CN=\\\"Bob\\\"x\", \"CN=\\\"Bob\\\"=x\", or \"O=\\\"Corp\\\"CN=a\" (missing comma).","commonSituations":"Values with unescaped trailing characters after quotes, hand-written DNs missing a separator between RDNs, or concatenation bugs when building DNs programmatically.","solutions":["Insert the missing separator ',' or '+' after the quoted value.","Remove the stray characters following the closing quote.","Move any extra characters inside the quoted string if they are part of the value: \"CN=\\\"Bob x\\\"\"."],"exampleFix":"// before\nname, err := pkixname.ParseDistinguishedName(\"CN=\\\"Bob\\\"O=Corp\")\n// after\nname, err := pkixname.ParseDistinguishedName(\"CN=\\\"Bob\\\",O=Corp\")","handlingStrategy":"validation","validationCode":"var afterQuoteRe = regexp.MustCompile(`\"[^,+;]`)\nfunc strayAfterQuote(dn string) bool { return afterQuoteRe.MatchString(dn) }","typeGuard":null,"tryCatchPattern":"name, err := pkixname.ParseDistinguishedName(dn)\nif err != nil {\n\treturn nil, fmt.Errorf(\"malformed DN %q: content after quoted value: %w\", dn, err)\n}","preventionTips":["Always follow a quoted value with ',' or '+'","Move extra characters inside the quotes if they belong to the value","Escape quotes inside values instead of nesting quote groups"],"tags":["x509","distinguished-name","parser","syntax"],"backgroundTag":"dn-malformed-syntax","analyzedSha":"1283425b60ec5f60d509ba4c791183d452923ff7","analyzedAt":"2026-09-02T04:06:41.601Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}