gravitational/teleport · error
multi-valued RDN must refer to the same attribute, but found
Error message
multi-valued RDN must refer to the same attribute, but found %q instead of %q, remaining tokens: %s
What it means
Multi-valued RDNs (components joined by '+') are only permitted when every value refers to the same attributeType (a parser deviation from RFC 2253 documented in ParseDistinguishedName). After seeing '+', parseRDNSequence peeks at the next attribute type and rejects it if it differs from the previous one in the current RDN.
Source
Thrown at api/utils/pkixname/parser.go:109
}
_ = markAttr(prevAttr)
for {
tok, ok := tokens.Peek()
if !ok {
return nil // end
}
switch tok.kind {
case tokenPlus:
tokens.PopSilently()
// Validate that prevAttr == current attr.
// If `!ok` just keep going and parseATV() will fail.
if nextTok, ok := tokens.Peek(); ok &&
nextTok.kind == tokenAttrType &&
nextTok.value != prevAttr {
return fmt.Errorf(
"multi-valued RDN must refer to the same attribute, but found %q instead of %q, remaining tokens: %s",
prevAttr,
nextTok.value,
tokens,
)
}
prevAttr, err = parseATV(dst, tokens)
if err != nil {
return err
}
case tokenComma:
tokens.PopSilently()
prevAttr, err = parseATV(dst, tokens)
if err != nil {
return err
}View on GitHub (pinned to 1283425b60)
Solutions
- Replace the '+' with a ',' so each attribute becomes its own RDN — but then ensure the attribute type is not repeated (see duplicate-attribute error)
- Drop one of the attributes if the differing one is not needed
- Only use '+' to give multiple values of the SAME attribute, e.g. 'OU=TeamA+OU=TeamB'
- Pre-validate that every '+'-joined component shares one attribute type
Example fix
// before
ParseDistinguishedName("CN=proxy+O=Teleport")
// after
ParseDistinguishedName("CN=proxy") // or "CN=proxy,O=Teleport" if the duplicate rule allows Defensive patterns
Strategy: validation
Validate before calling
func multiRDNAttrsValid(dn string) error {
for _, rdn := range strings.Split(dn, ",") {
attrs := strings.Split(rdn, "+")
types := map[string]bool{}
for _, a := range attrs {
kv := strings.SplitN(strings.TrimSpace(a), "=", 2)
if len(kv) == 2 { types[kv[0]] = true }
}
if len(types) > 1 { return fmt.Errorf("multi-valued RDN %q mixes attribute types", rdn) }
}
return nil
} Try / catch
if err := multiRDNAttrsValid(dn); err != nil { return err }
name, err := pkixname.ParseDistinguishedName(dn)
if err != nil { return fmt.Errorf("invalid DN %q: %w", dn, err) } Prevention
- Only use '+' to join multiple values of the SAME attribute type (e.g. 'OU=A+OU=B')
- When porting DNs from other certificates, flatten mixed '+' RDNs into separate components where the duplicate rule allows
- Treat this parser as stricter than RFC 4514 — read the documented deviations
When it happens
Trigger: ParseDistinguishedName('CN=proxy+O=Teleport') — '+' joins CN and O, which are different attribute types, so the parser returns this error with both attribute names and remaining tokens in the message.
Common situations: Users copy real-world X.509 subjects like 'CN=Name+serialNumber=123' or 'OU=Unit1+O=Org' from certificates, assuming standard RFC 4514 multi-valued RDN semantics that this stricter parser does not allow.
Related errors
- malformed RDNs: %w
- repeated attributeType %q, remaining tokens: %s
- not enough tokens to parse AttributeTypeValue, remaining tok
- invalid attributeType (bad character set): %q
- unknown attributeType %q, remaining tokens: %s
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/3a92c3d67156d016.
Report an issue: GitHub.