{"record":{"id":"8d679860f4f21b6c","repo":"gravitational/teleport","slug":"want-attributetype-or-found-eof","errorCode":null,"errorMessage":"want attributeType or '=', found EOF","messagePattern":"want attributeType or '=', found EOF","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/utils/pkixname/parser.go","lineNumber":578,"sourceCode":"\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:\n\t\treturn nil, fmt.Errorf(\"want escaped character, found EOF\")\n\tcase tokenizeStateStringQuote:\n\t\treturn nil, fmt.Errorf(\"want closing quote, found EOF\")\n\tcase tokenizeStateStringQuoteEnd:\n\t\t// OK.\n\tdefault:\n\t\t// This should not be reached. All states are handled above.\n\t\treturn nil, fmt.Errorf(\"found EOF (state=%d)\", state)\n\t}\n\n\treturn tokens, nil\n}","sourceCodeStart":560,"sourceCodeEnd":596,"githubUrl":"https://github.com/gravitational/teleport/blob/1283425b60ec5f60d509ba4c791183d452923ff7/api/utils/pkixname/parser.go#L560-L596","documentation":"The DN string ended after an attribute type was read but before '=' appeared — i.e. the input terminated in the middle of an attribute type with no assignment. This is the EOF variant of the 'want attributeType or =' error, raised in the end-of-input state check.","triggerScenarios":"Calling ParseDistinguishedName with a DN that is just a bare attribute type, e.g. \"CN\", \"O=Corp,CN\" (truncated after the last type), or \"CN=Bob,O\".","commonSituations":"Truncated config values, DN strings cut off at a length limit, typos dropping '=value', or building DNs with fmt.Sprintf and a missing argument.","solutions":["Complete the pair: append '=value', e.g. \"CN\" → \"CN=Bob\".","Remove the incomplete trailing attribute type.","Check where the DN string is produced/truncated (length limits, sprintf args) and fix the generator."],"exampleFix":"// before\nname, err := pkixname.ParseDistinguishedName(\"O=Corp,CN\")\n// after\nname, err := pkixname.ParseDistinguishedName(\"O=Corp,CN=Bob\")","handlingStrategy":"validation","validationCode":"func danglingAttrType(dn string) bool {\n\tparts := strings.Split(dn, \",\")\n\tlast := strings.TrimSpace(parts[len(parts)-1])\n\treturn !strings.Contains(last, \"=\")\n}","typeGuard":null,"tryCatchPattern":"name, err := pkixname.ParseDistinguishedName(dn)\nif err != nil {\n\tif strings.Contains(err.Error(), \"found EOF\") {\n\t\treturn nil, fmt.Errorf(\"DN %q is truncated: an attribute type lacks '=value'\", dn)\n\t}\n\treturn nil, err\n}","preventionTips":["Always emit type and value together when generating DNs","Check for truncation at storage/transport length limits","Add table tests covering partial DN inputs"],"tags":["x509","distinguished-name","parser","truncated-input"],"backgroundTag":"dn-truncated-attribute","analyzedSha":"1283425b60ec5f60d509ba4c791183d452923ff7","analyzedAt":"2026-09-02T04:06:41.601Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}