nats-io/nats-server · error

failed to decode escaped character: %s

Error message

failed to decode escaped character: %s

What it means

ParseDN parses an LDAP distinguished-name string. When it encounters a hex-escaped character (\XX), it decodes the two hex digits with encoding/hex; if the pair is not valid hex, it returns this error wrapping the decode failure.

Source

Thrown at internal/ldap/dn.go:163

		char := str[i]
		switch {
		case escaping:
			unescapedTrailingSpaces = 0
			escaping = false
			switch char {
			case ' ', '"', '#', '+', ',', ';', '<', '=', '>', '\\':
				buffer.WriteByte(char)
				continue
			}
			// Not a special character, assume hex encoded octet
			if len(str) == i+1 {
				return nil, errors.New("got corrupted escaped character")
			}

			dst := []byte{0}
			n, err := enchex.Decode([]byte(dst), []byte(str[i:i+2]))
			if err != nil {
				return nil, fmt.Errorf("failed to decode escaped character: %s", err)
			} else if n != 1 {
				return nil, fmt.Errorf("expected 1 byte when un-escaping, got %d", n)
			}
			buffer.WriteByte(dst[0])
			i++
		case char == '\\':
			unescapedTrailingSpaces = 0
			escaping = true
		case char == '=':
			attribute.Type = stringFromBuffer()
			// Special case: If the first character in the value is # the following data
			// is BER encoded. Throw an error since not supported right now.
			if len(str) > i+1 && str[i+1] == '#' {
				return nil, errors.New("unsupported BER encoding")
			}
		case char == ',' || char == '+':
			// We're done with this RDN or value, push it
			if len(attribute.Type) == 0 {

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Fix the DN string so every backslash escape is exactly two hex digits (e.g. \2C for comma)
  2. Check the source of the DN for double-escaping (e.g. \\2C read from config)
  3. Validate the DN with a regex/validator before passing it to ParseDN

Example fix

// before
dn, err := ParseDN("CN=\G1,OU=Engineering")
// after
dn, err := ParseDN("CN=\47 1,OU=Engineering") // or "CN=G1,OU=Engineering"
Defensive patterns

Strategy: validation

Validate before calling

var dnEscapeRe = regexp.MustCompile(`\\[0-9a-fA-F]{2}`)
// every '\' in a DN must be followed by two hex digits
if strings.Contains(dn, "\\") && !validEscapes(dn, dnEscapeRe) {
    return fmt.Errorf("DN %q has malformed hex escape", dn)
}

Try / catch

dn, err := ParseDN(input)
if err != nil {
    if strings.Contains(err.Error(), "failed to decode escaped character") {
        return fmt.Errorf("bad DN input %q: %w", input, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ParseDN with a DN containing a backslash escape followed by fewer than 2 valid hex characters, e.g. "CN=\G1" or "CN=\4".

Common situations: Hand-edited bind DNs or config files with improperly escaped special characters; DNs copied from tools that use different escaping conventions (e.g. \, instead of \2C).

Understand the failure class

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/a18285db9c5536c9. Report an issue: GitHub.