nats-io/nats-server · error

got corrupted escaped character

Error message

got corrupted escaped character

What it means

Returned by memStore.AddConsumer when creating a consumer in the in-memory stream store with a nil config or an empty consumer name. The memStore refuses to register a consumer it cannot identify or configure, since cfg is dereferenced (copied) right after the check. This is a programming/argument error, not a runtime state issue.

Source

Thrown at internal/ldap/dn.go:157

		buffer.Reset()
		unescapedTrailingSpaces = 0
		return s
	}

	for i := 0; i < len(str); i++ {
		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.

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Ensure the *ConsumerConfig passed to AddConsumer is non-nil; construct a default config if needed
  2. Ensure the consumer name argument is a non-empty string before calling AddConsumer
  3. Trace upstream where the config was lost (e.g. JSON decode of consumer create request) and reject it earlier with a proper API error

Example fix

// before
o, err := ms.AddConsumer(nil, name)
// after
if cfg == nil {
    cfg = &ConsumerConfig{}
}
if name == "" {
    return errors.New("consumer name required")
}
o, err := ms.AddConsumer(cfg, name)
Defensive patterns

Strategy: validation

Validate before calling

if cfg == nil || name == "" {
    return fmt.Errorf("consumer requires config and name")
}
o, err := ms.AddConsumer(cfg, name)

Type guard

func hasConsumerConfig(cfg *ConsumerConfig, name string) bool {
    return cfg != nil && name != ""
}

Try / catch

o, err := ms.AddConsumer(cfg, name)
if err != nil && strings.Contains(err.Error(), "bad consumer config") {
    // fix inputs: build default config, ensure non-empty name
}

Prevention

When it happens

Trigger: Calling memStore.AddConsumer(nil, "myconsumer") or memStore.AddConsumer(&ConsumerConfig{}, "") — i.e. nil cfg, or name == empty string.

Common situations: JetStream consumer creation where a template/default ConsumerConfig failed to load (nil pointer passed through), or code paths constructing consumers from API requests that omitted the durable/stream name field.

Related errors


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