gravitational/teleport · error

want attributeType, found %q: %s

Error message

want attributeType, found %q: %s

What it means

The DN tokenizer expects every RDN to start with an attribute type (letters, digits, '-', '.'). In the Init or NameComponent state, if the first character after a separator (or at the start of the DN) is not a valid attribute-type character, tokenization fails with this error, which includes the offending rune and the position/substring.

Source

Thrown at api/utils/pkixname/parser.go:491

				emitBuffer(tokenString)
				transitionToNameComponent(r)
				continue
			default:
				trailingSpaceBuf.WriteTo(buf) // whitespace copied back.
				trailingSpaceBuf.Reset()
				state = tokenizeStateString
				// Rune not consumed.
			}
		}

		switch state {
		case tokenizeStateInit, tokenizeStateNameComponent:
			switch {
			case isAttrType(r):
				state = tokenizeStateAttrType
				buf.WriteRune(r)
			default:
				return nil, fmt.Errorf("want attributeType, found %q: %s", r, errTrace(pos))
			}

		case tokenizeStateAttrType:
			switch {
			case isAttrType(r):
				buf.WriteRune(r)
			case r == '=':
				emitBuffer(tokenAttrType)
				emit(tokenEqual)
				state = tokenizeStateStringStart
			case r == ' ':
				emitBuffer(tokenAttrType)
				state = tokenizeStateAttrTypeEnd
			default:
				return nil, fmt.Errorf("want attributeType or '=', found %q: %s", r, errTrace(pos))
			}

		case tokenizeStateAttrTypeEnd:

View on GitHub (pinned to 1283425b60)

Solutions

  1. Remove empty components or stray separators from the DN string.
  2. Escape special characters in values with '\\', e.g. "O=\\+Corp", or quote the value: "O=\"+Corp\"".
  3. Ensure each comma/plus-separated segment begins with an attribute type like CN=, O=, OU=.
  4. Pre-validate the DN with a regex requiring each RDN to match [A-Za-z0-9.-]+=

Example fix

// before
name, err := pkixname.ParseDistinguishedName("CN=foo,,O=bar")
// after
name, err := pkixname.ParseDistinguishedName("CN=foo,O=bar")
Defensive patterns

Strategy: validation

Validate before calling

var rdnStartRe = regexp.MustCompile(`^[A-Za-z0-9.-]+\s*=`)
func validRDNStarts(dn string) bool {
	for _, part := range strings.Split(dn, ",") {
		if strings.TrimSpace(part) == "" || !rdnStartRe.MatchString(strings.TrimSpace(part)) {
			return false
		}
	}
	return true
}

Try / catch

name, err := pkixname.ParseDistinguishedName(dn)
if err != nil {
	return nil, fmt.Errorf("invalid distinguished name %q: %w", dn, err)
}

Prevention

When it happens

Trigger: Calling ParseDistinguishedName with a DN that starts with or follows a ','/';'/'+' with a non-attribute-type character, e.g. "=Bob", "CN=foo,,CN=bar", "CN=foo, =bar", or a value starting with an unescaped special character like "+CN=a".

Common situations: Empty RDN components from doubled commas, DNs with leading/trailing separators, copy-pasted DNs with stray punctuation, or values meant to be quoted/escaped that were not (e.g. "O=<Corp>").

Related errors


AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02). Data as JSON: /api/errors/68df971df505ff10. Report an issue: GitHub.