{"record":{"id":"57b12bc87730456e","repo":"stalwartlabs/stalwart","slug":"cluster-subscribererror-57b12b","errorCode":null,"errorMessage":"Cluster::SubscriberError","messagePattern":"Cluster::SubscriberError","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/coordinator/src/backend/nats/pubsub.rs","lineNumber":30,"sourceCode":"pub struct NatsPubSubStream {\n    subs: async_nats::Subscriber,\n}\n\nimpl NatsPubSub {\n    pub async fn publish(&self, topic: &'static str, message: Vec<u8>) -> trc::Result<()> {\n        self.client\n            .publish(topic, message.into())\n            .await\n            .map_err(|err| Error::new(EventType::Cluster(ClusterEvent::PublisherError)).reason(err))\n    }\n\n    pub async fn subscribe(&self, topic: &'static str) -> trc::Result<PubSubStream> {\n        self.client\n            .subscribe(topic)\n            .await\n            .map(|subs| PubSubStream::Nats(NatsPubSubStream { subs }))\n            .map_err(|err| {\n                Error::new(EventType::Cluster(ClusterEvent::SubscriberError)).reason(err)\n            })\n    }\n}\n\nimpl NatsPubSubStream {\n    pub async fn next(&mut self) -> Option<Msg> {\n        self.subs.next().await.map(Msg::Nats)\n    }\n}\n","sourceCodeStart":12,"sourceCodeEnd":40,"githubUrl":"https://github.com/stalwartlabs/stalwart/blob/e96200385781a6a9995a8b839ac27d6c75a983ee/crates/coordinator/src/backend/nats/pubsub.rs#L12-L40","documentation":"The NATS backend raises Cluster::SubscriberError when `client.subscribe(topic)` fails while setting up a subscription for the given subject. The failure is converted into a trc::Error with the async-nats error attached as the reason.","triggerScenarios":"Calling `NatsPubSub::subscribe(topic)` when async-nats returns an error from subscribe: invalid subject name, or the subscription request could not be sent because the connection is down.","commonSituations":"Malformed subject (empty string, spaces, leading/trailing dots); publishing/subscribing before the connection is established; NATS server unavailable.","solutions":["Check the attached reason for the exact async-nats subscribe error.","Ensure the subject is valid NATS syntax: dot-separated tokens, no spaces, allowed wildcards ('*', '>') only in subscribe subjects.","Confirm the NATS connection is alive before subscribing (await connect result / flush).","Retry subscribe after reconnecting if the server was temporarily unreachable."],"exampleFix":"// before\nlet subs = nats.subscribe(\"a b.c\").await?; // space invalid\n// after\nlet subs = nats.subscribe(\"events.cluster\").await?;","handlingStrategy":"validation","validationCode":"fn is_valid_nats_subject(s: &str) -> bool {\n    !s.is_empty()\n        && !s.starts_with('.')\n        && !s.ends_with('.')\n        && !s.contains(' ')\n        && s.split('.').all(|tok| !tok.is_empty())\n}","typeGuard":null,"tryCatchPattern":"match nats.subscribe(subject).await {\n    Ok(subs) => /* use subs */,\n    Err(e) => {\n        tracing::error!(subject, reason = ?e.reason(), \"nats subscribe failed\");\n        // fall back to resubscribe loop after reconnect\n    }\n}","preventionTips":["Validate subject syntax at the call site (dot-separated tokens, no spaces).","Only subscribe after the connect future has resolved successfully.","Re-subscribe on every reconnect event, since subscriptions may need re-establishment."],"tags":["nats","pubsub","subscriber","subject-name"],"backgroundTag":"invalid-argument-value","analyzedSha":"e96200385781a6a9995a8b839ac27d6c75a983ee","analyzedAt":"2026-09-06T22:07:17.982Z","contentChangedAt":"2026-09-06T22:07:17.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}