nats-io/nats-server · error
expected 1 byte when un-escaping, got %d
Error message
expected 1 byte when un-escaping, got %d
What it means
ParseDN decodes hex escapes into a single-byte buffer. If encoding/hex.Decode reports it consumed/produced a count other than 1 byte, the escape was not a valid single-byte pair, and this error is returned.
Source
Thrown at internal/ldap/dn.go:165
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 {
return nil, errors.New("incomplete type, value pair")
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Ensure each backslash escape is followed by exactly two hex characters and the DN is not truncated
- Trim/repair the DN source (file, env var, config) of stray whitespace or truncation
- Pre-validate DN length/escaping before calling ParseDN
Example fix
// before
dn, err := ParseDN("CN=Server\4")
// after
dn, err := ParseDN("CN=Server\40") Defensive patterns
Strategy: validation
Validate before calling
if len(dn) >= 1 && strings.HasSuffix(dn, "\\") {
return fmt.Errorf("DN %q ends with dangling escape", dn)
}
if !dnEscapeSequenceRegex.MatchString(dn) {
return fmt.Errorf("DN %q has invalid escape sequence", dn)
} Try / catch
dn, err := ParseDN(input)
if err != nil {
if strings.Contains(err.Error(), "expected 1 byte when un-escaping") {
return fmt.Errorf("truncated escape in DN %q: %w", input, err)
}
return err
} Prevention
- Never truncate DN strings (check file/env reads for corruption)
- Ensure all escapes are full two-char hex pairs
- Round-trip test: ParseDN DN, render back, compare
When it happens
Trigger: Calling ParseDN with a DN whose escape sequence decodes to something other than one byte — practically triggered by malformed input that slips past basic validation, or by a sliced escape substring shorter than 2 bytes at the end of the string.
Common situations: Truncated escape at end of DN string ("CN=A\4"), corrupted DN data read from files or network, off-by-one in DN-manipulation code that slices the string before parsing.
Related errors
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/4b5dc47c266f8259.
Report an issue: GitHub.