• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nats-io / nats-server / 19188141845

07 Nov 2025 01:16PM UTC coverage: 84.586% (-1.4%) from 86.033%
19188141845

push

github

web-flow
Add meta snapshot metrics to jsz monitoring (#7524)

Exposes snapshot related metrics under /jsz

```js
"meta_cluster": {
    "pending": 0,
    "snapshot": {
        "pending_entries": 1,
        "pending_size": 1314,
        "last_time": "2025-11-06T18:14:40.659678019Z", # UTC
        "last_duration": 161096363
     }
}
```

Signed-off-by: Waldemar Quevedo <wally@nats.io>

73649 of 87070 relevant lines covered (84.59%)

340562.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.01
/server/errors.go
1
// Copyright 2012-2025 The NATS Authors
2
// Licensed under the Apache License, Version 2.0 (the "License");
3
// you may not use this file except in compliance with the License.
4
// You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software
9
// distributed under the License is distributed on an "AS IS" BASIS,
10
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
// See the License for the specific language governing permissions and
12
// limitations under the License.
13

14
package server
15

16
import (
17
        "errors"
18
        "fmt"
19
)
20

21
var (
22
        // ErrConnectionClosed represents an error condition on a closed connection.
23
        ErrConnectionClosed = errors.New("connection closed")
24

25
        // ErrAuthentication represents an error condition on failed authentication.
26
        ErrAuthentication = errors.New("authentication error")
27

28
        // ErrAuthTimeout represents an error condition on failed authorization due to timeout.
29
        ErrAuthTimeout = errors.New("authentication timeout")
30

31
        // ErrAuthExpired represents an expired authorization due to timeout.
32
        ErrAuthExpired = errors.New("authentication expired")
33

34
        // ErrAuthProxyNotTrusted represents an error condition on failed authentication
35
        // due to a connection from a proxy not in the list of trusted proxies.
36
        ErrAuthProxyNotTrusted = errors.New("proxy is not trusted")
37

38
        // ErrAuthProxyRequired represents an error condition on failed authentication
39
        // due to a connection not coming from a proxy.
40
        ErrAuthProxyRequired = errors.New("proxy connection required")
41

42
        // ErrMaxPayload represents an error condition when the payload is too big.
43
        ErrMaxPayload = errors.New("maximum payload exceeded")
44

45
        // ErrMaxControlLine represents an error condition when the control line is too big.
46
        ErrMaxControlLine = errors.New("maximum control line exceeded")
47

48
        // ErrReservedPublishSubject represents an error condition when sending to a reserved subject, e.g. _SYS.>
49
        ErrReservedPublishSubject = errors.New("reserved internal subject")
50

51
        // ErrBadPublishSubject represents an error condition for an invalid publish subject.
52
        ErrBadPublishSubject = errors.New("invalid publish subject")
53

54
        // ErrBadSubject represents an error condition for an invalid subject.
55
        ErrBadSubject = errors.New("invalid subject")
56

57
        // ErrBadQualifier is used to error on a bad qualifier for a transform.
58
        ErrBadQualifier = errors.New("bad qualifier")
59

60
        // ErrBadClientProtocol signals a client requested an invalid client protocol.
61
        ErrBadClientProtocol = errors.New("invalid client protocol")
62

63
        // ErrTooManyConnections signals a client that the maximum number of connections supported by the
64
        // server has been reached.
65
        ErrTooManyConnections = errors.New("maximum connections exceeded")
66

67
        // ErrTooManyAccountConnections signals that an account has reached its maximum number of active
68
        // connections.
69
        ErrTooManyAccountConnections = errors.New("maximum account active connections exceeded")
70

71
        // ErrLeafNodeLoop signals a leafnode is trying to register for a cluster we already have registered.
72
        ErrLeafNodeLoop = errors.New("leafnode loop detected")
73

74
        // ErrTooManySubs signals a client that the maximum number of subscriptions per connection
75
        // has been reached.
76
        ErrTooManySubs = errors.New("maximum subscriptions exceeded")
77

78
        // ErrTooManySubTokens signals a client that the subject has too many tokens.
79
        ErrTooManySubTokens = errors.New("subject has exceeded number of tokens limit")
80

81
        // ErrClientConnectedToRoutePort represents an error condition when a client
82
        // attempted to connect to the route listen port.
83
        ErrClientConnectedToRoutePort = errors.New("attempted to connect to route port")
84

85
        // ErrClientConnectedToLeafNodePort represents an error condition when a client
86
        // attempted to connect to the leaf node listen port.
87
        ErrClientConnectedToLeafNodePort = errors.New("attempted to connect to leaf node port")
88

89
        // ErrLeafNodeHasSameClusterName represents an error condition when a leafnode is a cluster
90
        // and it has the same cluster name as the hub cluster.
91
        ErrLeafNodeHasSameClusterName = errors.New("remote leafnode has same cluster name")
92

93
        // ErrLeafNodeDisabled is when we disable leafnodes.
94
        ErrLeafNodeDisabled = errors.New("leafnodes disabled")
95

96
        // ErrConnectedToWrongPort represents an error condition when a connection is attempted
97
        // to the wrong listen port (for instance a LeafNode to a client port, etc...)
98
        ErrConnectedToWrongPort = errors.New("attempted to connect to wrong port")
99

100
        // ErrAccountExists is returned when an account is attempted to be registered
101
        // but already exists.
102
        ErrAccountExists = errors.New("account exists")
103

104
        // ErrBadAccount represents a malformed or incorrect account.
105
        ErrBadAccount = errors.New("bad account")
106

107
        // ErrReservedAccount represents a reserved account that can not be created.
108
        ErrReservedAccount = errors.New("reserved account")
109

110
        // ErrMissingAccount is returned when an account does not exist.
111
        ErrMissingAccount = errors.New("account missing")
112

113
        // ErrMissingService is returned when an account does not have an exported service.
114
        ErrMissingService = errors.New("service missing")
115

116
        // ErrBadServiceType is returned when latency tracking is being applied to non-singleton response types.
117
        ErrBadServiceType = errors.New("bad service response type")
118

119
        // ErrBadSampling is returned when the sampling for latency tracking is not 1 >= sample <= 100.
120
        ErrBadSampling = errors.New("bad sampling percentage, should be 1-100")
121

122
        // ErrAccountValidation is returned when an account has failed validation.
123
        ErrAccountValidation = errors.New("account validation failed")
124

125
        // ErrAccountExpired is returned when an account has expired.
126
        ErrAccountExpired = errors.New("account expired")
127

128
        // ErrNoAccountResolver is returned when we attempt an update but do not have an account resolver.
129
        ErrNoAccountResolver = errors.New("account resolver missing")
130

131
        // ErrAccountResolverUpdateTooSoon is returned when we attempt an update too soon to last request.
132
        ErrAccountResolverUpdateTooSoon = errors.New("account resolver update too soon")
133

134
        // ErrAccountResolverSameClaims is returned when same claims have been fetched.
135
        ErrAccountResolverSameClaims = errors.New("account resolver no new claims")
136

137
        // ErrStreamImportAuthorization is returned when a stream import is not authorized.
138
        ErrStreamImportAuthorization = errors.New("stream import not authorized")
139

140
        // ErrStreamImportBadPrefix is returned when a stream import prefix contains wildcards.
141
        ErrStreamImportBadPrefix = errors.New("stream import prefix can not contain wildcard tokens")
142

143
        // ErrStreamImportDuplicate is returned when a stream import is a duplicate of one that already exists.
144
        ErrStreamImportDuplicate = errors.New("stream import already exists")
145

146
        // ErrServiceImportAuthorization is returned when a service import is not authorized.
147
        ErrServiceImportAuthorization = errors.New("service import not authorized")
148

149
        // ErrImportFormsCycle is returned when an import would form a cycle.
150
        ErrImportFormsCycle = errors.New("import forms a cycle")
151

152
        // ErrCycleSearchDepth is returned when we have exceeded our maximum search depth..
153
        ErrCycleSearchDepth = errors.New("search cycle depth exhausted")
154

155
        // ErrClientOrRouteConnectedToGatewayPort represents an error condition when
156
        // a client or route attempted to connect to the Gateway port.
157
        ErrClientOrRouteConnectedToGatewayPort = errors.New("attempted to connect to gateway port")
158

159
        // ErrWrongGateway represents an error condition when a server receives a connect
160
        // request from a remote Gateway with a destination name that does not match the server's
161
        // Gateway's name.
162
        ErrWrongGateway = errors.New("wrong gateway")
163

164
        // ErrGatewayNameHasSpaces signals that the gateway name contains spaces, which is not allowed.
165
        ErrGatewayNameHasSpaces = errors.New("gateway name cannot contain spaces")
166

167
        // ErrNoSysAccount is returned when an attempt to publish or subscribe is made
168
        // when there is no internal system account defined.
169
        ErrNoSysAccount = errors.New("system account not setup")
170

171
        // ErrRevocation is returned when a credential has been revoked.
172
        ErrRevocation = errors.New("credentials have been revoked")
173

174
        // ErrServerNotRunning is used to signal an error that a server is not running.
175
        ErrServerNotRunning = errors.New("server is not running")
176

177
        // ErrServerNameHasSpaces signals that the server name contains spaces, which is not allowed.
178
        ErrServerNameHasSpaces = errors.New("server name cannot contain spaces")
179

180
        // ErrBadMsgHeader signals the parser detected a bad message header
181
        ErrBadMsgHeader = errors.New("bad message header detected")
182

183
        // ErrMsgHeadersNotSupported signals the parser detected a message header
184
        // but they are not supported on this server.
185
        ErrMsgHeadersNotSupported = errors.New("message headers not supported")
186

187
        // ErrNoRespondersRequiresHeaders signals that a client needs to have headers
188
        // on if they want no responders behavior.
189
        ErrNoRespondersRequiresHeaders = errors.New("no responders requires headers support")
190

191
        // ErrClusterNameConfigConflict signals that the options for cluster name in cluster and gateway are in conflict.
192
        ErrClusterNameConfigConflict = errors.New("cluster name conflicts between cluster and gateway definitions")
193

194
        // ErrClusterNameRemoteConflict signals that a remote server has a different cluster name.
195
        ErrClusterNameRemoteConflict = errors.New("cluster name from remote server conflicts")
196

197
        // ErrClusterNameHasSpaces signals that the cluster name contains spaces, which is not allowed.
198
        ErrClusterNameHasSpaces = errors.New("cluster name cannot contain spaces")
199

200
        // ErrMalformedSubject is returned when a subscription is made with a subject that does not conform to subject rules.
201
        ErrMalformedSubject = errors.New("malformed subject")
202

203
        // ErrSubscribePermissionViolation is returned when processing of a subscription fails due to permissions.
204
        ErrSubscribePermissionViolation = errors.New("subscribe permission violation")
205

206
        // ErrNoTransforms signals no subject transforms are available to map this subject.
207
        ErrNoTransforms = errors.New("no matching transforms available")
208

209
        // ErrCertNotPinned is returned when pinned certs are set and the certificate is not in it
210
        ErrCertNotPinned = errors.New("certificate not pinned")
211

212
        // ErrDuplicateServerName is returned when processing a server remote connection and
213
        // the server reports that this server name is already used in the cluster.
214
        ErrDuplicateServerName = errors.New("duplicate server name")
215

216
        // ErrMinimumVersionRequired is returned when a connection is not at the minimum version required.
217
        ErrMinimumVersionRequired = errors.New("minimum version required")
218

219
        // ErrInvalidMappingDestination is used for all subject mapping destination errors
220
        ErrInvalidMappingDestination = errors.New("invalid mapping destination")
221

222
        // ErrInvalidMappingDestinationSubject is used to error on a bad transform destination mapping
223
        ErrInvalidMappingDestinationSubject = fmt.Errorf("%w: invalid transform", ErrInvalidMappingDestination)
224

225
        // ErrMappingDestinationNotUsingAllWildcards is used to error on a transform destination not using all of the token wildcards
226
        ErrMappingDestinationNotUsingAllWildcards = fmt.Errorf("%w: not using all of the token wildcard(s)", ErrInvalidMappingDestination)
227

228
        // ErrUnknownMappingDestinationFunction is returned when a subject mapping destination contains an unknown mustache-escaped mapping function.
229
        ErrUnknownMappingDestinationFunction = fmt.Errorf("%w: unknown function", ErrInvalidMappingDestination)
230

231
        // ErrMappingDestinationIndexOutOfRange is returned when the mapping destination function is passed an out of range wildcard index value for one of it's arguments
232
        ErrMappingDestinationIndexOutOfRange = fmt.Errorf("%w: wildcard index out of range", ErrInvalidMappingDestination)
233

234
        // ErrMappingDestinationNotEnoughArgs is returned when the mapping destination function is not passed enough arguments
235
        ErrMappingDestinationNotEnoughArgs = fmt.Errorf("%w: not enough arguments passed to the function", ErrInvalidMappingDestination)
236

237
        // ErrMappingDestinationInvalidArg is returned when the mapping destination function is passed and invalid argument
238
        ErrMappingDestinationInvalidArg = fmt.Errorf("%w: function argument is invalid or in the wrong format", ErrInvalidMappingDestination)
239

240
        // ErrMappingDestinationTooManyArgs is returned when the mapping destination function is passed too many arguments
241
        ErrMappingDestinationTooManyArgs = fmt.Errorf("%w: too many arguments passed to the function", ErrInvalidMappingDestination)
242

243
        // ErrMappingDestinationNotSupportedForImport is returned when you try to use a mapping function other than wildcard in a transform that needs to be reversible (i.e. an import)
244
        ErrMappingDestinationNotSupportedForImport = fmt.Errorf("%w: the only mapping function allowed for import transforms is {{Wildcard()}}", ErrInvalidMappingDestination)
245
)
246

247
// mappingDestinationErr is a type of subject mapping destination error
248
type mappingDestinationErr struct {
249
        token string
250
        err   error
251
}
252

253
func (e *mappingDestinationErr) Error() string {
4✔
254
        return fmt.Sprintf("%s in %s", e.err, e.token)
4✔
255
}
4✔
256

257
func (e *mappingDestinationErr) Is(target error) bool {
×
258
        return target == ErrInvalidMappingDestination
×
259
}
×
260

261
// configErr is a configuration error.
262
type configErr struct {
263
        token  token
264
        reason string
265
}
266

267
// Source reports the location of a configuration error.
268
func (e *configErr) Source() string {
220✔
269
        return fmt.Sprintf("%s:%d:%d", e.token.SourceFile(), e.token.Line(), e.token.Position())
220✔
270
}
220✔
271

272
// Error reports the location and reason from a configuration error.
273
func (e *configErr) Error() string {
194✔
274
        if e.token != nil {
385✔
275
                return fmt.Sprintf("%s: %s", e.Source(), e.reason)
191✔
276
        }
191✔
277
        return e.reason
3✔
278
}
279

280
// unknownConfigFieldErr is an error reported in pedantic mode.
281
type unknownConfigFieldErr struct {
282
        configErr
283
        field string
284
}
285

286
// Error reports that an unknown field was in the configuration.
287
func (e *unknownConfigFieldErr) Error() string {
21✔
288
        return fmt.Sprintf("%s: unknown field %q", e.Source(), e.field)
21✔
289
}
21✔
290

291
// configWarningErr is an error reported in pedantic mode.
292
type configWarningErr struct {
293
        configErr
294
        field string
295
}
296

297
// Error reports a configuration warning.
298
func (e *configWarningErr) Error() string {
8✔
299
        return fmt.Sprintf("%s: invalid use of field %q: %s", e.Source(), e.field, e.reason)
8✔
300
}
8✔
301

302
// processConfigErr is the result of processing the configuration from the server.
303
type processConfigErr struct {
304
        errors   []error
305
        warnings []error
306
}
307

308
// Error returns the collection of errors separated by new lines,
309
// warnings appear first then hard errors.
310
func (e *processConfigErr) Error() string {
207✔
311
        var msg string
207✔
312
        for _, err := range e.Warnings() {
214✔
313
                msg += err.Error() + "\n"
7✔
314
        }
7✔
315
        for _, err := range e.Errors() {
421✔
316
                msg += err.Error() + "\n"
214✔
317
        }
214✔
318
        return msg
207✔
319
}
320

321
// Warnings returns the list of warnings.
322
func (e *processConfigErr) Warnings() []error {
208✔
323
        return e.warnings
208✔
324
}
208✔
325

326
// Errors returns the list of errors.
327
func (e *processConfigErr) Errors() []error {
323✔
328
        return e.errors
323✔
329
}
323✔
330

331
// errCtx wraps an error and stores additional ctx information for tracing.
332
// Does not print or return it unless explicitly requested.
333
type errCtx struct {
334
        error
335
        ctx string
336
}
337

338
func NewErrorCtx(err error, format string, args ...any) error {
6✔
339
        return &errCtx{err, fmt.Sprintf(format, args...)}
6✔
340
}
6✔
341

342
// Unwrap implement to work with errors.Is and errors.As
343
func (e *errCtx) Unwrap() error {
5✔
344
        if e == nil {
5✔
345
                return nil
×
346
        }
×
347
        return e.error
5✔
348
}
349

350
// Context for error
351
func (e *errCtx) Context() string {
3✔
352
        if e == nil {
3✔
353
                return ""
×
354
        }
×
355
        return e.ctx
3✔
356
}
357

358
// UnpackIfErrorCtx return Error or, if type is right error and context
359
func UnpackIfErrorCtx(err error) string {
5✔
360
        if e, ok := err.(*errCtx); ok {
8✔
361
                if _, ok := e.error.(*errCtx); ok {
4✔
362
                        return fmt.Sprint(UnpackIfErrorCtx(e.error), ": ", e.Context())
1✔
363
                }
1✔
364
                return fmt.Sprint(e.Error(), ": ", e.Context())
2✔
365
        }
366
        return err.Error()
2✔
367
}
368

369
// implements: go 1.13 errors.Unwrap(err error) error
370
// TODO replace with native code once we no longer support go1.12
371
func errorsUnwrap(err error) error {
5✔
372
        u, ok := err.(interface {
5✔
373
                Unwrap() error
5✔
374
        })
5✔
375
        if !ok {
5✔
376
                return nil
×
377
        }
×
378
        return u.Unwrap()
5✔
379
}
380

381
// ErrorIs implements: go 1.13 errors.Is(err, target error) bool
382
// TODO replace with native code once we no longer support go1.12
383
func ErrorIs(err, target error) bool {
4✔
384
        // this is an outright copy of go 1.13 errors.Is(err, target error) bool
4✔
385
        // removed isComparable
4✔
386
        if err == nil || target == nil {
4✔
387
                return err == target
×
388
        }
×
389

390
        for {
13✔
391
                if err == target {
13✔
392
                        return true
4✔
393
                }
4✔
394
                if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
5✔
395
                        return true
×
396
                }
×
397
                // TODO: consider supporing target.Is(err). This would allow
398
                // user-definable predicates, but also may allow for coping with sloppy
399
                // APIs, thereby making it easier to get away with them.
400
                if err = errorsUnwrap(err); err == nil {
5✔
401
                        return false
×
402
                }
×
403
        }
404
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc