gravitational/teleport · error

want '+' or ',', found %q: %s

Error message

want '+' or ',', found %q: %s

What it means

After a closing quote of a quoted attribute value, the tokenizer only accepts a '+' (multi-valued RDN) or ','/' ;' (next RDN). Any other character after the quoted string is rejected. Whitespace is skipped before this check, so the error means real stray content follows the quoted value.

Source

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

			}

		case tokenizeStateStringQuote:
			switch r {
			case '\\':
				escapeStart()
			case '"':
				emitBuffer(tokenString)
				state = tokenizeStateStringQuoteEnd
			default:
				buf.WriteRune(r)
			}

		case tokenizeStateStringQuoteEnd:
			switch r {
			case '+', ',', ';':
				transitionToNameComponent(r)
			default:
				return nil, fmt.Errorf("want '+' or ',', found %q: %s", r, errTrace(pos))
			}
		}
	}

	// Input ended, check the final state.
	switch state {
	case tokenizeStateInit:
		// OK.
	case tokenizeStateNameComponent:
		return nil, fmt.Errorf("want attributeType, found EOF")
	case tokenizeStateAttrType:
		return nil, fmt.Errorf("want attributeType or '=', found EOF")
	case tokenizeStateAttrTypeEnd:
		return nil, fmt.Errorf("want '=' attributeValue, found EOF")
	case tokenizeStateStringStart, tokenizeStateString, tokenizeStateStringEnd:
		// OK.
		emitBuffer(tokenString)
	case tokenizeStateStringEscape:

View on GitHub (pinned to 1283425b60)

Solutions

  1. Insert the missing separator ',' or '+' after the quoted value.
  2. Remove the stray characters following the closing quote.
  3. Move any extra characters inside the quoted string if they are part of the value: "CN=\"Bob x\"".

Example fix

// before
name, err := pkixname.ParseDistinguishedName("CN=\"Bob\"O=Corp")
// after
name, err := pkixname.ParseDistinguishedName("CN=\"Bob\",O=Corp")
Defensive patterns

Strategy: validation

Validate before calling

var afterQuoteRe = regexp.MustCompile(`"[^,+;]`)
func strayAfterQuote(dn string) bool { return afterQuoteRe.MatchString(dn) }

Try / catch

name, err := pkixname.ParseDistinguishedName(dn)
if err != nil {
	return nil, fmt.Errorf("malformed DN %q: content after quoted value: %w", dn, err)
}

Prevention

When it happens

Trigger: Calling ParseDistinguishedName with content after a quoted value, e.g. "CN=\"Bob\"x", "CN=\"Bob\"=x", or "O=\"Corp\"CN=a" (missing comma).

Common situations: Values with unescaped trailing characters after quotes, hand-written DNs missing a separator between RDNs, or concatenation bugs when building DNs programmatically.

Related errors


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