gravitational/teleport · error
hexstring not supported: %s
Error message
hexstring not supported: %s
What it means
ParseDistinguishedName parses an RFC 2253-like DN but deliberately does not support hex-encoded values ("#" followed by hex bytes, e.g. "#0402ABCD"). When the tokenizer reaches the value position (tokenizeStateStringStart) and sees '#', it rejects the DN outright because the library only supports string attribute values.
Source
Thrown at api/utils/pkixname/parser.go:456
state == tokenizeStateAttrTypeEnd ||
state == tokenizeStateStringStart ||
state == tokenizeStateStringQuoteEnd) {
continue
}
// string start/end handling.
// This happens early because we sometimes transition to "string" without
// consuming the rune.
switch state {
case tokenizeStateStringStart:
switch r {
case '+', ',', ';':
// Empty strings are valid.
emitBuffer(tokenString)
transitionToNameComponent(r)
continue
case '#':
return nil, fmt.Errorf("hexstring not supported: %s", errTrace(pos))
case '"':
// Note that a quoted string may be empty.
state = tokenizeStateStringQuote
continue
default:
state = tokenizeStateString
// Rune not consumed.
}
case tokenizeStateStringEnd:
switch r {
case ' ':
trailingSpaceBuf.WriteRune(r)
continue
case '+', ',', ';':
trailingSpaceBuf.Reset() // whitespace discarded.
emitBuffer(tokenString)
transitionToNameComponent(r)View on GitHub (pinned to 1283425b60)
Solutions
- Replace the hex value with its plain string equivalent, e.g. "CN=Example" instead of "CN=#13024578616D706C65".
- Use a known symbolic attribute type (C, O, OU, CN, ST, L, STREET, POSTALCODE, SERIALNUMBER) with a string value.
- If a custom OID value is needed, express it as a string: "1.2.3.4=myvalue" (parsed into ExtraNames), not a hex blob.
- Pre-validate the DN in caller code and reject/transform any '#'-prefixed values before calling ParseDistinguishedName.
Example fix
// before
name, err := pkixname.ParseDistinguishedName("CN=#13024578616D706C65")
// after
name, err := pkixname.ParseDistinguishedName("CN=Example") Defensive patterns
Strategy: validation
Validate before calling
func hasHexValue(dn string) bool {
for i := 0; i < len(dn); i++ {
if dn[i] == '#' && (i == 0 || dn[i-1] == ',' || dn[i-1] == '+' || dn[i-1] == ' ' || dn[i-1] == '=') {
return true
}
}
return false
}
// if hasHexValue(dn) { convert or reject before ParseDistinguishedName } Try / catch
name, err := pkixname.ParseDistinguishedName(dn)
if err != nil {
if strings.Contains(err.Error(), "hexstring not supported") {
// fall back: convert hex value to string form or surface a clear config error
return nil, fmt.Errorf("DN %q uses unsupported hex values; use string values", dn)
}
return nil, err
} Prevention
- Never write attribute values with a leading '#' in configs
- Convert hex-encoded values to plain strings before storing DNs
- Add a unit test for any DN template shipped in config
When it happens
Trigger: Calling pkixname.ParseDistinguishedName with any DN where an attribute value begins with '#', e.g. "CN=#1302AB" or "OID.1.2.3=#041102". The error is raised in tokenize at the exact position of the '#'.
Common situations: Copy-pasting DNs from OpenSSL output, LDAP directories, or certificate subjects that use hex-encoded (BER/DER) values, or DNs written with leading '#' to 'protect' values from tools interpreting them. Also common when migrating configs from libraries that accept hexstrings (e.g. Go's crypto/x509 or OpenLDAP).
Related errors
- want attributeType, found %q: %s
- want attributeType or '=', found %q: %s
- want '=' attributeValue, found %q: %s
- special character %q not quoted: %s
- unexpected escaped character %q: %s
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/9f72d476a8874730.
Report an issue: GitHub.