gravitational/teleport · error
repeated attributeType %q, remaining tokens: %s
Error message
repeated attributeType %q, remaining tokens: %s
What it means
parseRDNSequence tracks attribute types already seen across comma-separated RDNs via seenAttrs. When the same attributeType appears twice in distinct RDNs (e.g. 'CN=a,CN=b'), markAttr returns this error. Multi-valued RDNs joined by '+' are allowed, but the same attribute may only appear once per comma-separated component.
Source
Thrown at api/utils/pkixname/parser.go:82
}
dst := &pkix.Name{}
if tokens.Len() == 0 {
return dst, nil
}
if err := parseRDNSequence(dst, *tokens); err != nil {
return nil, fmt.Errorf("malformed RDNs: %w", err)
}
return dst, nil
}
// parseRDNSequence parses a RelativeDistinguishedName sequence, ie, a sequence
// of AttributeTypeAndValue separated by commas or pluses.
func parseRDNSequence(dst *pkix.Name, tokens tokenList) error {
seenAttrs := make(map[string]struct{})
markAttr := func(attr string) error {
if _, ok := seenAttrs[attr]; ok {
return fmt.Errorf("repeated attributeType %q, remaining tokens: %s", attr, tokens)
}
seenAttrs[attr] = struct{}{}
return nil
}
prevAttr, err := parseATV(dst, tokens)
if err != nil {
return err
}
_ = markAttr(prevAttr)
for {
tok, ok := tokens.Peek()
if !ok {
return nil // end
}
switch tok.kind {View on GitHub (pinned to 1283425b60)
Solutions
- Remove the duplicate attributeType from the DN string
- Merge values into one attribute where the parser supports lists (e.g. OU=a,OU=b fails too — combine into one value or a multi-valued RDN of the same type)
- Move the second value into a different supported attribute (e.g. use OU for additional organization units)
- Pre-validate the DN for duplicate keys before passing it to ParseDistinguishedName
Example fix
// before
ParseDistinguishedName("CN=proxy,CN=proxy-alt")
// after
ParseDistinguishedName("CN=proxy") Defensive patterns
Strategy: validation
Validate before calling
func noDuplicateAttrs(dn string) error {
seen := map[string]bool{}
for _, part := range strings.Split(dn, ",") {
kv := strings.SplitN(strings.TrimSpace(part), "=", 2)
if len(kv) == 2 {
if seen[kv[0]] { return fmt.Errorf("duplicate attribute %q in DN", kv[0]) }
seen[kv[0]] = true
}
}
return nil
} Try / catch
if err := noDuplicateAttrs(dn); err != nil { return err }
name, err := pkixname.ParseDistinguishedName(dn)
if err != nil { return fmt.Errorf("invalid DN %q: %w", dn, err) } Prevention
- Never repeat an attribute type across comma-separated components
- For repeated org units, decide on a single value or restructure with OU instead of multiple O's
- Generate DNs from a fixed template instead of concatenating user input
When it happens
Trigger: ParseDistinguishedName('CN=server,CN=alias.example.com') — a second CN (or O, OU, etc.) after a comma triggers markAttr. Note the first markAttr error (for the initial attribute) is deliberately discarded (_ = markAttr(prevAttr)), so only repeats from the second RDN onward surface.
Common situations: Templates or configs that concatenate subject components and emit 'O=Org1,O=Org2' instead of using a single multi-valued RDN 'O=Org1+O=Org2' or an OU list; users expecting RFC 4514 behavior where repeated attributes are legal.
Related errors
- invalid attributeType (bad character set): %q
- malformed RDNs: %w
- multi-valued RDN must refer to the same attribute, but found
- not enough tokens to parse AttributeTypeValue, remaining tok
- unknown attributeType %q, remaining tokens: %s
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/f8a39537f8b4bf16.
Report an issue: GitHub.