nats-io/nats-server · error · ApiError (JSMirrorInvalidSubjectFilter)
10151
10151
Error message
%w %s
What it means
A mirror's SubjectTransforms entry contains an invalid source subject (or a source/destination mapping that fails ValidateMapping). The server wraps ErrBadSubject with the offending subject and returns JSMirrorInvalidSubjectFilterError (10151) via JSStreamInvalidConfigError during mirror config validation.
Source
Thrown at server/stream.go:2138
return StreamConfig{}, NewJSMirrorDurableConsumerCfgInvalidError()
}
if cfg.Mirror.FilterSubject != _EMPTY_ {
return StreamConfig{}, NewJSMirrorDurableConsumerCfgInvalidError()
}
}
if cfg.Mirror.FilterSubject != _EMPTY_ && len(cfg.Mirror.SubjectTransforms) != 0 {
return StreamConfig{}, NewJSMirrorMultipleFiltersNotAllowedError()
}
if cfg.SubjectDeleteMarkerTTL > 0 {
// Delete markers cannot be configured on a mirror as it would result in new
// tombstones which would use up sequence numbers, diverging from the origin
// stream.
return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("subject delete markers forbidden on mirrors"))
}
// Check subject filters overlap.
for outer, tr := range cfg.Mirror.SubjectTransforms {
if tr.Source != _EMPTY_ && !IsValidSubject(tr.Source) {
return StreamConfig{}, NewJSMirrorInvalidSubjectFilterError(fmt.Errorf("%w %s", ErrBadSubject, tr.Source))
}
err := ValidateMapping(tr.Source, tr.Destination)
if err != nil {
return StreamConfig{}, NewJSMirrorInvalidTransformDestinationError(err)
}
for inner, innertr := range cfg.Mirror.SubjectTransforms {
if inner != outer && SubjectsCollide(tr.Source, innertr.Source) {
return StreamConfig{}, NewJSMirrorOverlappingSubjectFiltersError()
}
}
}
// Do not perform checks if External is provided, as it could lead to
// checking against itself (if sourced stream name is the same on different JetStream)
if cfg.Mirror.External == nil {
if !isValidAssetName(cfg.Mirror.Name) {
return StreamConfig{}, NewJSMirrorInvalidStreamNameError()View on GitHub (pinned to 3a66a489d2)
Solutions
- Fix the SubjectTransforms source subject to a valid NATS subject (no spaces, valid tokens/wildcards)
- Ensure each transform has both a valid non-empty Source and Destination
- Validate subjects with server IsValidSubject semantics (tokens separated by '.', legal wildcard use) before submitting
Example fix
// before
tf := SubjectTransformConfig{Source: "foo..bar", Destination: "baz"}
// after
tf := SubjectTransformConfig{Source: "foo.bar", Destination: "baz"} Defensive patterns
Strategy: validation
Validate before calling
for _, tr := range cfg.Mirror.SubjectTransforms {
if tr.Source != "" && !subjectIsValid(tr.Source) {
return fmt.Errorf("invalid mirror transform source: %q", tr.Source)
}
if err := validateMapping(tr.Source, tr.Destination); err != nil {
return err
}
} Try / catch
var ec *jsapi.APIError
if errors.As(err, &ec) && ec.ErrorCode == 10151 {
// inspect Subjects transforms, fix invalid source, resubmit
} Prevention
- Validate all transform subjects with server-equivalent rules before submit
- Avoid building subject strings with raw string concatenation
- Add unit tests covering transform source/destination shapes
When it happens
Trigger: AddStream/UpdateStream with Mirror.SubjectTransforms where tr.Source is non-empty and !IsValidSubject(tr.Source) — e.g. empty destination, trailing dot, invalid wildcard placement, or spaces in the subject.
Common situations: Typos in transform subjects like 'foo..bar' or 'foo bar'; constructing transforms programmatically with empty/invalid source strings; configs hand-edited with wildcards in illegal positions.
Related errors
- invalid subject transform source '%s' for the mirror: %w
- subject transform from '%s' to '%s' for the mirror: %w
- 10145
- invalid mapping destination: wildcard index out of range
- invalid mapping destination: not enough arguments passed to
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/c7624d913b4db69c.
Report an issue: GitHub.