{"record":{"id":"21ae9657dcf9445f","repo":"nats-io/nats-server","slug":"mqtt-authentication-username-not-compatible-with-p","errorCode":null,"errorMessage":"mqtt authentication username not compatible with presence of users/nkeys","messagePattern":"mqtt authentication username not compatible with presence of users/nkeys","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":230,"sourceCode":"\tsparkbCertificatesTopicPrefix = []byte(\"$sparkplug/certificates/\")\n)\n\nvar (\n\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\")","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L212-L248","documentation":"When MQTT authentication is configured via `mqtt { username/token }`, those credentials are mutually exclusive with the server's global `users`/`nkeys` authorization lists. If any users or nkeys are configured and the MQTT section also defines a username (or token), validation returns this error (server/mqtt.go:718) because the two auth mechanisms cannot be combined.","triggerScenarios":"Config `mqtt { username: \"...\" }` together with a `users` or `nkeys` array; adding MQTT credentials to a deployment that already uses users/nkeys for other clients.","commonSituations":"Adding MQTT support to an existing server secured with users/nkeys; mixing MQTT token auth with per-user credentials in one config; TestMQTTUserMixWithUsersNKeys documents this exact scenario.","solutions":["Remove the mqtt username/token and instead give MQTT clients an entry in the `users` list (with or without password)","Or remove the global `users`/`nkeys` definitions if you intend to use only MQTT-level auth","For granular MQTT permissions, configure a dedicated user in `users` used by MQTT clients rather than the mqtt block"],"exampleFix":"# before\nmqtt { username: \"mqtt\", password: \"pwd\" }\nusers = [{user: \"app\", password: \"s3cret\"}]\n# after\nusers = [{user: \"app\", password: \"s3cret\"}, {user: \"mqtt\", password: \"pwd\"}]","handlingStrategy":"validation","validationCode":"// Reject the combination before deploy\nif cfg.MQTT != nil && (cfg.MQTT.Username != \"\" || cfg.MQTT.Token != \"\") && (len(cfg.Users) > 0 || len(cfg.Nkeys) > 0) {\n  return errors.New(\"mqtt username/token cannot be combined with users/nkeys\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Choose one auth model per server: users/nkeys lists OR mqtt-level credentials","Represent MQTT clients as entries in the users list for uniform auth","Run nats-server -t in CI to catch config conflicts early"],"tags":["mqtt","configuration","authentication","users"],"backgroundTag":"conflicting-auth-config","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}