nats-io/nats-server · warning
unsupported BER encoding
Error message
unsupported BER encoding
What it means
memStore.Snapshot is a deliberately unimplemented method in the in-memory store; it always returns a 'no impl' error. The memStore is used for ephemeral/no-persistence streams, so full snapshotting is unsupported. Callers must use EncodedStreamState instead when working with a memStore-backed stream.
Source
Thrown at internal/ldap/dn.go:177
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")
}
attribute.Value = stringFromBuffer()
rdn.Attributes = append(rdn.Attributes, attribute)
attribute = new(AttributeTypeAndValue)
if char == ',' {
dn.RDNs = append(dn.RDNs, rdn)
rdn = new(RelativeDN)
rdn.Attributes = make([]*AttributeTypeAndValue, 0)
}
case char == ' ' && buffer.Len() == 0:
// ignore unescaped leading spaces
continue
default:View on GitHub (pinned to 3a66a489d2)
Solutions
- Do not call Snapshot on memory-backed streams; use EncodedStreamState or StreamState instead
- Check the store type (StorageMemory) before invoking Snapshot and skip/handle accordingly
- Use the generic snapshot path only for fileStore-backed streams
Example fix
// before
snap, err := store.Snapshot(10*time.Second, true, true)
// after
if _, isMem := store.(*memStore); isMem {
return errors.New("snapshot not supported for memory streams")
}
snap, err := store.Snapshot(10*time.Second, true, true) Defensive patterns
Strategy: fallback
Validate before calling
if _, isMem := store.(*memStore); isMem {
// use EncodedStreamState / StreamState instead of Snapshot
} Type guard
func supportsSnapshot(s interface{}) bool {
_, isMem := s.(*memStore)
return !isMem
} Try / catch
snap, err := store.Snapshot(d, includeDeleted, checkMsgs)
if err != nil && strings.Contains(err.Error(), "no impl") {
// fall back to memory-store state access
} Prevention
- Check stream storage type (memory vs file) before snapshotting
- Prefer interface guards (Snapshotter type assertion) over blind calls
- Document that memory streams don't support snapshots in tooling
When it happens
Trigger: Calling Snapshot(_, _, _, _) on a *memStore instance — e.g. generic store code that snapshots all stream types without checking the storage type.
Common situations: Monitoring or migration tooling calling the Store interface's Snapshot method on a stream configured with memory storage; interface-level code assuming all store implementations support snapshots.
Related errors
- got corrupted escaped character
- incomplete type, value pair
- DN ended with incomplete type, value pair
- errors.New(strings.Join(errs, "\n"))
- subject does not match jwt content
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/41f5d826ce0e0564.
Report an issue: GitHub.