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.