Skip to content

Errors

Every sentinel is declared with errors.NewSentinel and carries a namespaced kind, so its identity survives crossing a process boundary and it captures no stack at package initialisation.

Sentinel Kind Returned when
ErrNoStoreDir nats.no_store_dir JetStream is set with no StoreDir
ErrNoClusterName nats.no_cluster_name Routes is set with no ClusterName
ErrNoTarget nats.no_target A client has neither a URL nor an in-process server
ErrAmbiguousTarget nats.ambiguous_target A client has both
ErrNotReady nats.not_ready An embedded server did not accept connections in time
ErrUnbounded nats.unbounded A stream or bucket would be created with no limit

Why these are refusals rather than defaults

Each one is a case where a sensible-looking default would fail later, quietly, somewhere else.

A JetStream server with no store directory writes where it pleases. That differs by host, and survives a deployment differently on each one, so the first time it matters is a restart that lost data on one node and not the others.

A server with routes but no cluster name does not mesh. It starts, it accepts clients, and it is alone — which looks exactly like a healthy single server until somebody expects replication.

A client with two targets has been told two different things. Picking one is how a service ends up talking to a broker nobody thought it was talking to.

A stream with no limit is bounded by the disk. Every JetStream limit — MaxAge, MaxMsgs, MaxBytes — defaults to unlimited, and NATS' own documentation warns that this exhausts storage. Failing at construction is cheaper than failing at 3am.