{"record":{"id":"eb5cbece453e5721","repo":"nats-io/nats-server","slug":"10157","errorCode":"10157","errorMessage":"origin stream has direct get set, mirror has it disabled","messagePattern":"origin stream has direct get set, mirror has it disabled","errorType":"validation","errorClass":"ApiError (JSPedanticErrF)","httpStatus":400,"severity":"error","filePath":"server/stream.go","lineNumber":2171,"sourceCode":"\t\t// checking against itself (if sourced stream name is the same on different JetStream)\n\t\tif cfg.Mirror.External == nil {\n\t\t\tif !isValidAssetName(cfg.Mirror.Name) {\n\t\t\t\treturn StreamConfig{}, NewJSMirrorInvalidStreamNameError()\n\t\t\t}\n\t\t\t// We do not require other stream to exist anymore, but if we can see it check payloads.\n\t\t\texists, maxMsgSize, subs := hasStream(cfg.Mirror.Name)\n\t\t\tif len(subs) > 0 {\n\t\t\t\tstreamSubs = append(streamSubs, subs...)\n\t\t\t}\n\t\t\tif exists {\n\t\t\t\tif cfg.MaxMsgSize > 0 && maxMsgSize > 0 && cfg.MaxMsgSize < maxMsgSize {\n\t\t\t\t\treturn StreamConfig{}, NewJSMirrorMaxMessageSizeTooBigError()\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Determine if we are inheriting direct gets.\n\t\t\tif exists, ocfg := getStream(cfg.Mirror.Name); exists {\n\t\t\t\tif pedantic && cfg.MirrorDirect != ocfg.AllowDirect {\n\t\t\t\t\treturn StreamConfig{}, NewJSPedanticError(fmt.Errorf(\"origin stream has direct get set, mirror has it disabled\"))\n\t\t\t\t}\n\t\t\t\tcfg.MirrorDirect = ocfg.AllowDirect\n\t\t\t} else if js := s.getJetStream(); js != nil && js.isClustered() {\n\t\t\t\t// Could not find it here. If we are clustered we can look it up.\n\t\t\t\tif sa := js.streamAssignmentOrInflight(acc.Name, cfg.Mirror.Name); sa != nil {\n\t\t\t\t\tif pedantic && cfg.MirrorDirect != sa.Config.AllowDirect {\n\t\t\t\t\t\treturn StreamConfig{}, NewJSPedanticError(fmt.Errorf(\"origin stream has direct get set, mirror has it disabled\"))\n\t\t\t\t\t}\n\t\t\t\t\tcfg.MirrorDirect = sa.Config.AllowDirect\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif cfg.Mirror.External.DeliverPrefix != _EMPTY_ {\n\t\t\t\tdeliveryPrefixes = append(deliveryPrefixes, cfg.Mirror.External.DeliverPrefix)\n\t\t\t}\n\n\t\t\tif cfg.Mirror.External.ApiPrefix != _EMPTY_ {\n\t\t\t\tapiPrefixes = append(apiPrefixes, cfg.Mirror.External.ApiPrefix)","sourceCodeStart":2153,"sourceCodeEnd":2189,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/stream.go#L2153-L2189","documentation":"In pedantic mode, when a mirror's origin stream is found locally, the server compares cfg.MirrorDirect with the origin's AllowDirect setting. If the mirror's MirrorDirect flag disagrees (typically mirror has it disabled while origin has direct gets), JSPedanticError (10157) is returned instead of silently inheriting the value.","triggerScenarios":"AddStream/UpdateStream of a Mirror with pedantic checks enabled, where getStream(cfg.Mirror.Name) succeeds locally and cfg.MirrorDirect != origin cfg.AllowDirect.","commonSituations":"Creating a mirror with MirrorDirect explicitly false/omitted while the origin stream has AllowDirect: true; templates that hard-code MirrorDirect=false; migrating configs between environments where the origin was changed to AllowDirect.","solutions":["Set MirrorDirect to true on the mirror config to match the origin's AllowDirect","Remove the explicit MirrorDirect value so it inherits from the origin","Set AllowDirect: false on the origin stream if direct gets are not wanted"],"exampleFix":"// before\nsc := StreamConfig{Name: \"m\", Mirror: &StreamSource{Name: \"origin\"}, MirrorDirect: false}\n// after\nsc := StreamConfig{Name: \"m\", Mirror: &StreamSource{Name: \"origin\"}, MirrorDirect: true}","handlingStrategy":"validation","validationCode":"if origin != nil && cfg.MirrorDirect != origin.AllowDirect {\n    cfg.MirrorDirect = origin.AllowDirect // inherit before AddStream\n}","typeGuard":null,"tryCatchPattern":"var pe *jsapi.APIError\nif errors.As(err, &pe) && pe.ErrorCode == 10157 {\n    // fetch origin AllowDirect, set MirrorDirect accordingly, retry\n}","preventionTips":["Don't hard-code MirrorDirect; inherit it from the origin stream","Check origin's AllowDirect whenever templates change","Enable pedantic checks in CI to catch drift early"],"tags":["jetstream","mirror","allow-direct","pedantic"],"backgroundTag":"mirror-direct-mismatch","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}