{"record":{"id":"2fce74f9b66061c9","repo":"nats-io/nats-server","slug":"mqtt-requires-jetstream-to-be-enabled-if-running-i","errorCode":null,"errorMessage":"mqtt requires JetStream to be enabled if running in standalone mode","messagePattern":"mqtt requires JetStream to be enabled if running in standalone mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":234,"sourceCode":"\tmqttPingResponse     = []byte{mqttPacketPingResp, 0x0}\n\tmqttProtoName        = []byte(\"MQTT\")\n\tmqttOldProtoName     = []byte(\"MQIsdp\")\n\tmqttSessJailDur      = mqttSessFlappingJailDur\n\tmqttFlapCleanItvl    = mqttSessFlappingCleanupInterval\n\tmqttRetainedCacheTTL = mqttDefaultRetainedCacheTTL\n)\n\nvar (\n\terrMQTTNotWebsocketPort           = errors.New(\"MQTT clients over websocket must connect to the Websocket port, not the MQTT port\")\n\terrMQTTTopicFilterCannotBeEmpty   = errors.New(\"topic filter cannot be empty\")\n\terrMQTTMalformedVarInt            = errors.New(\"malformed variable int\")\n\terrMQTTSecondConnectPacket        = errors.New(\"received a second CONNECT packet\")\n\terrMQTTServerNameMustBeSet        = errors.New(\"mqtt requires server name to be explicitly set\")\n\terrMQTTUserMixWithUsersNKeys      = errors.New(\"mqtt authentication username not compatible with presence of users/nkeys\")\n\terrMQTTTokenMixWIthUsersNKeys     = errors.New(\"mqtt authentication token not compatible with presence of users/nkeys\")\n\terrMQTTAckWaitMustBePositive      = errors.New(\"ack wait must be a positive value\")\n\terrMQTTJSAPITimeoutMustBePositive = errors.New(\"JS API timeout must be a positive value\")\n\terrMQTTStandaloneNeedsJetStream   = errors.New(\"mqtt requires JetStream to be enabled if running in standalone mode\")\n\terrMQTTConnFlagReserved           = errors.New(\"connect flags reserved bit not set to 0\")\n\terrMQTTWillAndRetainFlag          = errors.New(\"if Will flag is set to 0, Will Retain flag must be 0 too\")\n\terrMQTTPasswordFlagAndNoUser      = errors.New(\"password flag set but username flag is not\")\n\terrMQTTCIDEmptyNeedsCleanFlag     = errors.New(\"when client ID is empty, clean session flag must be set to 1\")\n\terrMQTTEmptyWillTopic             = errors.New(\"empty Will topic not allowed\")\n\terrMQTTEmptyUsername              = errors.New(\"empty user name not allowed\")\n\terrMQTTTopicIsEmpty               = errors.New(\"topic cannot be empty\")\n\terrMQTTPacketIdentifierIsZero     = errors.New(\"packet identifier cannot be 0\")\n\terrMQTTUnsupportedCharacters      = errors.New(\"character not supported for MQTT topics\")\n\terrMQTTInvalidSession             = errors.New(\"invalid MQTT session\")\n\terrMQTTInvalidRetainFlags         = errors.New(\"invalid retained message flags\")\n\terrMQTTInvalidRetainedMessage     = errors.New(\"invalid retained message\")\n\terrMQTTSessionCollision           = errors.New(\"stored session does not match client ID\")\n\terrMQTTInvalidPublishLength       = errors.New(\"invalid publish message, variable header exceeds remaining length\")\n\terrMQTTAckPipelineStopped         = errors.New(\"QoS1 PUBACK pipeline has shut down while admitting a message, \" +\n\t\t\"abandoning the wait for its JetStream ack; failing the connection, \" +\n\t\t\"the client will re-send unacknowledged PUBLISH packets on reconnect\")\n)","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L216-L252","documentation":"MQTT fan-out in NATS is backed by JetStream, so when the server runs strictly standalone (no cluster, gateway, or leaf-node connections) JetStream must be explicitly enabled. If opts.JetStream is false and no clustering/gateway/leaf ports or remotes are configured, option validation at server/mqtt.go:736 rejects the config.","triggerScenarios":"Enabling opts.MQTT (listen port set) while opts.JetStream is false and opts.Cluster.Port, opts.Gateway.Port, opts.LeafNode.Port are 0 and len(opts.LeafNode.Remotes) == 0; also expected in TestMQTTServerNameRequired/TestMQTTStandaloneRequiresJetStream.","commonSituations":"Adding an mqtt listen block to a simple standalone NATS config that has no jetstream block, or disabling JetStream via flags while keeping MQTT enabled.","solutions":["Enable JetStream: set opts.JetStream = true or add a jetstream {} block to the config file.","Alternatively connect the server to a cluster, gateway, or leaf node so it is not standalone.","If JetStream is not wanted, remove the MQTT listener configuration."],"exampleFix":"// before\no := &server.Options{MQTT: server.MQTTOpts{Port: 1883}}\n// after\no := &server.Options{MQTT: server.MQTTOpts{Port: 1883}, JetStream: true}","handlingStrategy":"validation","validationCode":"if o.MQTT.Port != 0 && !o.JetStream &&\n    o.Cluster.Port == 0 && o.Gateway.Port == 0 &&\n    o.LeafNode.Port == 0 && len(o.LeafNode.Remotes) == 0 {\n    return fmt.Errorf(\"enable JetStream or clustering before enabling MQTT\")\n}","typeGuard":null,"tryCatchPattern":"if err := opts.Process(); err != nil {\n    if strings.Contains(err.Error(), \"requires JetStream\") {\n        opts.JetStream = true // then retry NewServer\n    }\n}","preventionTips":["Whenever enabling MQTT, enable JetStream in the same change.","Keep mqtt and jetstream blocks co-located in config files so one implies the other.","Run NewServer in a startup smoke test to catch config drift early."],"tags":["mqtt","jetstream","config","startup"],"backgroundTag":"jetstream-not-enabled","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}