{"record":{"id":"79315faed34d0f03","repo":"nats-io/nats-server","slug":"invalid-domain-name-derived-q-is-not-a-valid-sub","errorCode":null,"errorMessage":"invalid domain name: derived %q is not a valid subject","messagePattern":"invalid domain name: derived %q is not a valid subject","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/jetstream.go","lineNumber":2929,"sourceCode":"\t\tfor a, d := range o.JsAccDefaultDomain {\n\t\t\tsacc := DEFAULT_SYSTEM_ACCOUNT\n\t\t\tif o.SystemAccount != _EMPTY_ {\n\t\t\t\tsacc = o.SystemAccount\n\t\t\t}\n\t\t\tif a == sacc {\n\t\t\t\treturn fmt.Errorf(\"system account %q can not be in default_js_domain\", a)\n\t\t\t}\n\t\t\tif d == _EMPTY_ {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif sub := fmt.Sprintf(jsDomainAPI, d); !IsValidSubject(sub) {\n\t\t\t\treturn fmt.Errorf(\"default_js_domain contains account %q with invalid domain name %q\", a, d)\n\t\t\t}\n\t\t}\n\t}\n\tif o.JetStreamDomain != _EMPTY_ {\n\t\tif subj := fmt.Sprintf(jsDomainAPI, o.JetStreamDomain); !IsValidSubject(subj) {\n\t\t\treturn fmt.Errorf(\"invalid domain name: derived %q is not a valid subject\", subj)\n\t\t}\n\n\t\tif !isValidName(o.JetStreamDomain) {\n\t\t\treturn fmt.Errorf(\"invalid domain name: may not contain ., * or >\")\n\t\t}\n\t}\n\t// If not clustered no checks needed past here.\n\tif !o.JetStream || o.Cluster.Port == 0 {\n\t\treturn nil\n\t}\n\tif o.ServerName == _EMPTY_ {\n\t\treturn fmt.Errorf(\"jetstream cluster requires `server_name` to be set\")\n\t}\n\tif o.Cluster.Name == _EMPTY_ {\n\t\treturn fmt.Errorf(\"jetstream cluster requires `cluster.name` to be set\")\n\t}\n\n\th := strings.ToLower(o.JetStreamExtHint)","sourceCodeStart":2911,"sourceCodeEnd":2947,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jetstream.go#L2911-L2947","documentation":"The server-wide `jetstream_domain` option (o.JetStreamDomain) is also embedded into an API subject via jsDomainAPI and must therefore yield a valid NATS subject. Validation happens before the stricter character check, so this error fires first for domains that break subject syntax (invalid characters, empty tokens, bad wildcards).","triggerScenarios":"Configuring `jetstream_domain` in the server config with a value where fmt.Sprintf(jsDomainAPI, domain) is not a valid subject — e.g. containing spaces, leading/trailing dots, or invalid characters.","commonSituations":"Misconfigured multi-domain setups; environment-specific config templating injecting an empty or whitespace-padded domain; using reserved wildcard characters in the domain.","solutions":["Correct `jetstream_domain` so the derived subject is valid: use only alphanumeric, underscore, hyphen and dot characters, with no spaces or empty segments.","Remove the `jetstream_domain` option if a single default domain is intended.","Restart the server to re-run validation."],"exampleFix":"// before\njetstream_domain: \".foo.\"\n// after\njetstream_domain: \"foo\"","handlingStrategy":"validation","validationCode":"if cfg.JetStreamDomain != \"\" {\n    sub := \"$JS.\" + cfg.JetStreamDomain + \".API\"\n    if !nats.IsValidSubject(sub) {\n        return fmt.Errorf(\"jetstream_domain %q derives invalid subject\", cfg.JetStreamDomain)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a regex like ^[A-Za-z0-9_-]+$ to validate jetstream_domain before deploy.","Avoid templating that can inject empty or whitespace values.","Test generated configs with a validation pass in CI."],"tags":["jetstream","configuration","domain","subject-validation"],"backgroundTag":"invalid-server-config","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}