{"record":{"id":"9f7b96f34e955fd9","repo":"nats-io/nats-server","slug":"unable-to-get-subject-transform-for-source-v","errorCode":null,"errorMessage":"unable to get subject transform for source: %v","messagePattern":"unable to get subject transform for source: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/stream.go","lineNumber":2799,"sourceCode":"\t\t\t\t\tmset.cfg.Sources = append(mset.cfg.Sources, s)\n\t\t\t\t\tmset.cfgMu.Unlock()\n\n\t\t\t\t\tvar si *sourceInfo\n\n\t\t\t\t\tif len(s.SubjectTransforms) == 0 {\n\t\t\t\t\t\tsi = &sourceInfo{name: s.Name, iname: s.iname, sf: s.FilterSubject}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsi = &sourceInfo{name: s.Name, iname: s.iname}\n\t\t\t\t\t\tsi.trs = make([]*subjectTransform, len(s.SubjectTransforms))\n\t\t\t\t\t\tsi.sfs = make([]string, len(s.SubjectTransforms))\n\t\t\t\t\t\tfor i := range s.SubjectTransforms {\n\t\t\t\t\t\t\t// err can be ignored as already validated in config check\n\t\t\t\t\t\t\tsi.sfs[i] = s.SubjectTransforms[i].Source\n\t\t\t\t\t\t\tvar err error\n\t\t\t\t\t\t\tsi.trs[i], err = NewSubjectTransform(s.SubjectTransforms[i].Source, s.SubjectTransforms[i].Destination)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\tmset.mu.Unlock()\n\t\t\t\t\t\t\t\treturn fmt.Errorf(\"unable to get subject transform for source: %v\", err)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tmset.sources[s.iname] = si\n\t\t\t\t\tif needsStartingSeqNum == nil {\n\t\t\t\t\t\tneedsStartingSeqNum = make(map[string]struct{})\n\t\t\t\t\t}\n\t\t\t\t\tneedsStartingSeqNum[s.iname] = struct{}{}\n\t\t\t\t} else {\n\t\t\t\t\t// source already exists\n\t\t\t\t\tdelete(currentIName, s.iname)\n\t\t\t\t}\n\n\t\t\t\t// Remove the source if it still exists, but only if not using a pre-existing consumer.\n\t\t\t\tif s.Consumer == nil {\n\t\t\t\t\tdelete(currentConsumers, getSourcingConsumerIName(s, cfg.Sources))\n\t\t\t\t}","sourceCodeStart":2781,"sourceCodeEnd":2817,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/stream.go#L2781-L2817","documentation":"While (re)building the internal source state for a stream's mirror/sources, JetStream creates a SubjectTransform for each source's Source/Destination pair via NewSubjectTransform; if construction fails, the stream update/create is aborted with this error. It indicates one of the configured source subject transforms is invalid.","triggerScenarios":"StreamConfig.Sources[i].SubjectTransform (Source/Destination) that NewSubjectTransform cannot compile, e.g. invalid wildcard or malformed subject in a source's transform, added during UpdateStream.","commonSituations":"Typo in transform source like 'foo.>' vs 'foo.*' misuse, empty Destination, or invalid subject characters in a mirrored-source transform.","solutions":["Validate each Sources[i].SubjectTransform subject strings with nats.SubjectTransformPre or by testing NewSubjectTransform client-side logic (valid subject syntax).","Fix or remove the offending Source/Destination pair in the stream config and retry UpdateStream.","Check the wrapped error (%v) to see which transform rule was rejected."],"exampleFix":"// before\nSources: []StreamSource{{Name: \"OTHER\", SubjectTransform: &SubjectTransformConfig{Source: \"foo..bar\"}}}\n// after\nSources: []StreamSource{{Name: \"OTHER\", SubjectTransform: &SubjectTransformConfig{Source: \"foo.*\", Destination: \"baz.*\"}}}","handlingStrategy":"validation","validationCode":"for _, s := range cfg.Sources {\n    if t := s.SubjectTransform; t != nil {\n        if err := validTransformPair(t.Source, t.Destination); err != nil { return err }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.HasPrefix(err.Error(), \"unable to get subject transform for source\") { /* fix Sources[i].SubjectTransform */ }","preventionTips":["Validate source transforms with a subject-syntax check before UpdateStream.","Keep wildcard token counts equal between Source and Destination."],"tags":["jetstream","subject-transform","stream-sources"],"backgroundTag":"invalid-subject-transform","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}