{"record":{"id":"0b4257cf6e3a582e","repo":"gravitational/teleport","slug":"want-attributetype-or-found-q-s","errorCode":null,"errorMessage":"want attributeType or '=', found %q: %s","messagePattern":"want attributeType or '=', found %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/utils/pkixname/parser.go","lineNumber":506,"sourceCode":"\t\t\t\tstate = tokenizeStateAttrType\n\t\t\t\tbuf.WriteRune(r)\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"want attributeType, found %q: %s\", r, errTrace(pos))\n\t\t\t}\n\n\t\tcase tokenizeStateAttrType:\n\t\t\tswitch {\n\t\t\tcase isAttrType(r):\n\t\t\t\tbuf.WriteRune(r)\n\t\t\tcase r == '=':\n\t\t\t\temitBuffer(tokenAttrType)\n\t\t\t\temit(tokenEqual)\n\t\t\t\tstate = tokenizeStateStringStart\n\t\t\tcase r == ' ':\n\t\t\t\temitBuffer(tokenAttrType)\n\t\t\t\tstate = tokenizeStateAttrTypeEnd\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"want attributeType or '=', found %q: %s\", r, errTrace(pos))\n\t\t\t}\n\n\t\tcase tokenizeStateAttrTypeEnd:\n\t\t\tswitch r {\n\t\t\tcase '=':\n\t\t\t\temit(tokenEqual)\n\t\t\t\tstate = tokenizeStateStringStart\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"want '=' attributeValue, found %q: %s\", r, errTrace(pos))\n\t\t\t}\n\n\t\tcase tokenizeStateString:\n\t\t\tswitch r {\n\t\t\tcase '+', ',', ';':\n\t\t\t\temitBuffer(tokenString)\n\t\t\t\ttransitionToNameComponent(r)\n\t\t\tcase '\\\\':\n\t\t\t\tescapeStart()","sourceCodeStart":488,"sourceCodeEnd":524,"githubUrl":"https://github.com/gravitational/teleport/blob/1283425b60ec5f60d509ba4c791183d452923ff7/api/utils/pkixname/parser.go#L488-L524","documentation":"While reading an attribute type, the tokenizer only accepts more type characters, whitespace (moving to AttrTypeEnd), or '='. Any other rune after the type starts is rejected with this error, which identifies the offending rune and position.","triggerScenarios":"Calling ParseDistinguishedName where a value or separator appears before '=' in an attribute, e.g. \"CN:Bob\", \"CN=Bob,O=\" followed by another char, or \"CN?Bob\", or typing the DN in the wrong order like \"Bob=CN\".","commonSituations":"Using ':' instead of '=' (common LDAP ldif-style confusion), typos in key=value syntax, or DNs copied from formats that use different delimiters.","solutions":["Replace the offending delimiter with '=' between attribute type and value, e.g. \"CN:Bob\" → \"CN=Bob\".","Ensure the DN is a sequence of type=value pairs separated by ',' or '+'.","Pre-validate that every component matches `attrtype[ ]*=` before parsing."],"exampleFix":"// before\nname, err := pkixname.ParseDistinguishedName(\"CN:Bob\")\n// after\nname, err := pkixname.ParseDistinguishedName(\"CN=Bob\")","handlingStrategy":"validation","validationCode":"var atvRe = regexp.MustCompile(`^[A-Za-z0-9.-]+\\s*=`)\nfunc startsWithTypeEquals(component string) bool {\n\treturn atvRe.MatchString(strings.TrimSpace(component))\n}","typeGuard":null,"tryCatchPattern":"name, err := pkixname.ParseDistinguishedName(dn)\nif err != nil {\n\treturn nil, fmt.Errorf(\"malformed DN %q (expected type=value): %w\", dn, err)\n}","preventionTips":["Always use '=' (not ':' or other delimiters) between type and value","Lint DN templates for the pattern attr=value","Test DN generation code with example output"],"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"}