{"record":{"id":"8f043ae6b3c1e7b6","repo":"nats-io/nats-server","slug":"subject-transform-from-s-to-s-for-the-mirror","errorCode":null,"errorMessage":"subject transform from '%s' to '%s' for the mirror: %w","messagePattern":"subject transform from '(.+?)' to '(.+?)' for the mirror: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/stream.go","lineNumber":951,"sourceCode":"\n\t// If mirror, check if the transforms (if any) are valid.\n\tif cfg.Mirror != nil {\n\t\tif len(cfg.Mirror.SubjectTransforms) == 0 {\n\t\t\tif cfg.Mirror.FilterSubject != _EMPTY_ && !IsValidSubject(cfg.Mirror.FilterSubject) {\n\t\t\t\tjsa.mu.Unlock()\n\t\t\t\treturn nil, fmt.Errorf(\"subject filter '%s' for the mirror %w\", cfg.Mirror.FilterSubject, ErrBadSubject)\n\t\t\t}\n\t\t} else {\n\t\t\tfor _, st := range cfg.Mirror.SubjectTransforms {\n\t\t\t\tif st.Source != _EMPTY_ && !IsValidSubject(st.Source) {\n\t\t\t\t\tjsa.mu.Unlock()\n\t\t\t\t\treturn nil, fmt.Errorf(\"invalid subject transform source '%s' for the mirror: %w\", st.Source, ErrBadSubject)\n\t\t\t\t}\n\t\t\t\t// check the transform, if any, is valid\n\t\t\t\tif st.Destination != _EMPTY_ {\n\t\t\t\t\tif _, err = NewSubjectTransform(st.Source, st.Destination); err != nil {\n\t\t\t\t\t\tjsa.mu.Unlock()\n\t\t\t\t\t\treturn nil, fmt.Errorf(\"subject transform from '%s' to '%s' for the mirror: %w\", st.Source, st.Destination, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Setup our internal indexed names here for sources and check if the transforms (if any) are valid.\n\tfor _, ssi := range cfg.Sources {\n\t\tif len(ssi.SubjectTransforms) == 0 {\n\t\t\t// check the filter, if any, is valid\n\t\t\tif ssi.FilterSubject != _EMPTY_ && !IsValidSubject(ssi.FilterSubject) {\n\t\t\t\tjsa.mu.Unlock()\n\t\t\t\treturn nil, fmt.Errorf(\"subject filter '%s' for the source: %w\", ssi.FilterSubject, ErrBadSubject)\n\t\t\t}\n\t\t} else {\n\t\t\tfor _, st := range ssi.SubjectTransforms {\n\t\t\t\tif st.Source != _EMPTY_ && !IsValidSubject(st.Source) {\n\t\t\t\t\tjsa.mu.Unlock()","sourceCodeStart":933,"sourceCodeEnd":969,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/stream.go#L933-L969","documentation":"When a mirror's subject transform has a destination, NewSubjectTransform validates source/destination compatibility (token counts, wildcards); this error wraps the underlying transform error, so the mirror config is rejected.","triggerScenarios":"AddStream/UpdateStream with a mirror SubjectTransforms entry whose Destination does not compose with its Source (e.g. more tokens in destination, illegal wildcard mapping).","commonSituations":"Writing transforms like source \"foo.*\" to destination \"bar.*.extra\", or destination containing wildcards the server cannot map from the source.","solutions":["Ensure the destination is structurally compatible with the source (matching token counts, wildcards only where the source has them).","Test the transform with NewSubjectTransform locally to see the underlying reason.","Remove the destination (empty) if no transform is actually wanted."],"exampleFix":"// before\n{Source: \"foo.*\", Destination: \"bar.*.extra\"}\n// after\n{Source: \"foo.*\", Destination: \"bar.*\"}","handlingStrategy":"validation","validationCode":"for _, st := range cfg.Mirror.SubjectTransforms {\n  if st.Destination != \"\" {\n    if _, err := server.NewSubjectTransform(st.Source, st.Destination); err != nil { return err }\n  }\n}","typeGuard":null,"tryCatchPattern":"_, err := js.AddStream(cfg)\nif err != nil && strings.Contains(err.Error(), \"subject transform from\") { /* adjust source/destination token structure */ }","preventionTips":["Keep destination token count equal to source; map wildcards 1:1.","Test transform pairs offline before deploying config."],"tags":["jetstream","mirror","subject-transform","validation"],"backgroundTag":"subject-transform-invalid-mapping","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}