gravitational/teleport · error

invalid attributeType (bad character set): %q

Error message

invalid attributeType (bad character set): %q

What it means

Attribute types that are not numeric OIDs must match attrTypeRegexp: start with a letter, followed by letters, digits or hyphens. Because the tokenizer also accepts '.' and digits in attribute positions, an attribute like '2.5x' or 'foo.bar' reaches parseATV, fails the OID regexp, then fails this character-set check and is rejected.

Source

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

	// Pop tokens before returning. We retain the tokens up until the end so
	// eventual errors include them in the message.
	defer func() {
		tokens.PopSilently()
		tokens.PopSilently()
		tokens.PopSilently()
	}()

	attr = t1.value
	value := t3.value

	// Parse as OID?
	if oidRegexp.MatchString(attr) {
		return attr, parseOIDExtraName(dst, attr, value)
	}
	// Verify attributeType character set.
	if !attrTypeRegexp.MatchString(attr) {
		return "", fmt.Errorf("invalid attributeType (bad character set): %q", attr)
	}

	switch attr {
	case "SERIALNUMBER":
		dst.SerialNumber = value
	case "CN":
		dst.CommonName = value
	case "OU":
		dst.OrganizationalUnit = append(dst.OrganizationalUnit, value)
	case "O":
		dst.Organization = append(dst.Organization, value)
	case "POSTALCODE":
		dst.PostalCode = append(dst.PostalCode, value)
	case "STREET":
		dst.StreetAddress = append(dst.StreetAddress, value)
	case "L":
		dst.Locality = append(dst.Locality, value)
	case "ST":

View on GitHub (pinned to 1283425b60)

Solutions

  1. Use plain short attribute names: CN, O, OU, C, ST, L, STREET, POSTALCODE, SERIALNUMBER
  2. For custom attributes, use a bare numeric OID without an 'oid.' prefix, e.g. '1.2.3.4=value'
  3. Replace underscores or dots in custom names with hyphens (still letter-first), or use an OID form
  4. Remove 'oid.'/'OID.' prefixes — they are documented as unsupported

Example fix

// before
ParseDistinguishedName("oid.2.5.4.3=proxy")
// after
ParseDistinguishedName("CN=proxy")
Defensive patterns

Strategy: validation

Validate before calling

var attrTypeRe = regexp.MustCompile(`^[A-Za-z]([A-Za-z0-9-])*$`)
var oidRe = regexp.MustCompile(`^\d+(\.\d+)*$`)
func attrTypeValid(dn string) error {
	for _, part := range strings.Split(dn, ",") {
		kv := strings.SplitN(strings.TrimSpace(part), "=", 2)
		if len(kv) == 2 && !oidRe.MatchString(kv[0]) && !attrTypeRe.MatchString(kv[0]) {
			return fmt.Errorf("attribute type %q has invalid characters", kv[0])
		}
	}
	return nil
}

Try / catch

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

Prevention

When it happens

Trigger: Attribute types containing dots (other than pure OIDs), underscores, leading digits mixed with non-OID shapes, or other symbols: ParseDistinguishedName('CN.NAME=x'), ParseDistinguishedName('1a.2b=v'), or 'OID.CN=x' (dot-prefixed forms).

Common situations: Users write 'oid.2.5.4.3=x' or 'OID.CN=x' which the parser explicitly does not support (documented deviation), or use snake_case attribute names like 'common_name' which fail the letter-start/charset rule.

Related errors


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