Eclipse Mosquitto / Troubleshooting

Mosquitto Rejects the MQTT Client Connection

Prove TCP reachability to the broker first, then read the MQTT CONNACK refusal code and match the listener-specific authentication on Mosquitto 2.1.x before changing any broker configuration.

The Mosquitto 2.1 release record deprecates the bare acl_file, password_file, and per_listener_settings options in favour of the mosquitto_acl_file and mosquitto_password_file plugins and new listener-specific options, with removal scheduled for 3.0. The official replacement guide maps each deprecated option to its listener-specific successor: allow_anonymous becomes listener_allow_anonymous, and plugins are loaded once with plugin_load then applied per listener with plugin_use. The password-file plugin page confirms the plugin is the preferred way of using a password file and that password files are generated with the mosquitto_passwd utility.[1][3][6]

The mosquitto_sub man page defines the observable symptom precisely: when the broker refuses the connection at the MQTT level, the client exit code is the CONNACK reason code. For MQTT 3.1.1, code 4 means bad username or password and code 5 means not authorized; MQTT v5 defines its own codes including 134 and 135 for the same two conditions. An operating-system TCP refusal with nothing listening is a different observation and must be excluded first.[5]

Applicability

Products
Eclipse Mosquitto
Scope
For Eclipse Mosquitto 2.1.x current stable (2.1.2, released 2026-02-09; 2.1.0 feature release 2026-01-29) where an MQTT client reaches the broker over TCP but the broker refuses the connection at the MQTT level. The main path uses the 2.1 listener-specific authentication model. Legacy 2.0.x bare password_file, acl_file, and per_listener_settings options are deprecated with removal in 3.0 and appear only in an explicitly version-gated compatibility branch. This page does not cover a broker that is unreachable over TCP, TLS/PSK certificate setup, or broker-to-broker bridges.[1][2][3][5]
Last verified

Symptoms

  • An MQTT client completes TCP to the broker port but the connection is refused at the MQTT level, observable as a nonzero mosquitto_sub exit code carrying the CONNACK reason (for example 4 or 5 under MQTT 3.1.1). A TCP connection failure, a TLS handshake failure, or a connected client that cannot publish to a topic is a different observation.[5]

Quick diagnosis

Prove TCP reachability first, then read the CONNACK refusal code and match the listener-specific authentication on Mosquitto 2.1.x. Never confuse an MQTT refusal with a TCP failure.

Safe / low risk

Prove TCP reachability before diagnosing authentication

Attempt a client connection with debug output against the broker host and port from the client network. If TCP itself fails, stop: this page does not apply and the fault is at the network, firewall, or broker-process layer. Only a completed TCP handshake followed by an MQTT-level refusal continues on this page.[5]

mosquitto_sub -h <host> -p <port> -t '<topic>' -d
Read-only

Record the installed Mosquitto release line

Record whether the broker tracks the current 2.1.x stable line or an older line, from the deployment package, container image tag, or broker startup record. The 2.1 listener-specific authentication model, the deprecated-option mapping, and the removal-in-3.0 schedule all depend on this version boundary; 2.0.x and 1.x behavior differs and must not be mixed into the main path.[1][2]

Read-only

Do not change broker authentication before classifying the refusal

Do not edit mosquitto.conf, credential files, or listener blocks before proving TCP reachability, reading the CONNACK code, and identifying which listener and authentication the client actually hits. An authentication change made before classification can lock out working clients without fixing the refused one.[3][5]

Interactive troubleshooter

Your answers stay in this browser tab. The tool does not connect to your systems or send diagnostic results.

Guided check / step 1

Safe diagnostic guidance

Is an MQTT client being refused by this broker?

Confirm the subject is a client connection attempt against this Mosquitto broker, not a bridge, a TLS handshake failure, or a connected client with topic problems.[5]

Read the complete diagnostic tree without using the controls
  1. Is an MQTT client being refused by this broker?

    Confirm the subject is a client connection attempt against this Mosquitto broker, not a bridge, a TLS handshake failure, or a connected client with topic problems.[5]

    • Yes, a refused client connectionDoes TCP to the broker host and port complete?
    • No, a different observationInvestigate the actual observation
  2. Does TCP to the broker host and port complete?

    Prove TCP reachability first: the client must complete the TCP handshake to the configured broker host and port. Only a completed handshake followed by an MQTT CONNACK refusal continues; anything else exits this page before any authentication reasoning.[5]

    • Yes, TCP completesWhich CONNACK refusal code does the client report?
    • No, TCP failsTCP fails: investigate the path, bind address, or broker process
    • Cannot confirm TCP stateCollect a broker refusal evidence packet
  3. Which CONNACK refusal code does the client report?

    Read the client exit code, which carries the CONNACK reason on MQTT-level refusal. Under MQTT 3.1.1, 4 means bad username or password and 5 means not authorized; under MQTT v5, use the documented v5 codes for the negotiated protocol version.[5]

    • Bad username or passwordWhat authentication does the reached listener carry on the installed release line?
    • Not authorizedWhat authentication does the reached listener carry on the installed release line?
    • Different code or unclear refusalCollect a broker refusal evidence packet
  4. What authentication does the reached listener carry on the installed release line?

    Identify the exact listener block the client reaches and the authentication bound to it. On 2.1.x that means listener_allow_anonymous, a password-file plugin binding, or another plugin; the deprecated bare options belong only to an explicitly version-gated 2.0.x branch.[4][3][1]

    • Credentials offered but rejected by the storeCorrect the credential store bound to the reached listener
    • Anonymous or unconfigured access denied hereGive the reached listener an explicit scoped authentication decision
    • Broker runs 2.0.x with legacy option placementMigrate the 2.0.x legacy options to the listener-specific model
    • Listener configuration is unclearCollect a broker refusal evidence packet
  5. Correct the credential store bound to the reached listener

    Recreate or correct the username entry with mosquitto_passwd, confirm the file is readable by the broker user, and confirm the password-file plugin is the authentication bound to the reached listener on 2.1.x. Retest with the same client and credentials.[3][6][4]

  6. Give the reached listener an explicit scoped authentication decision

    Decide explicitly for the reached listener: bind credential authentication to it, or allow anonymous access narrowly with listener_allow_anonymous only on a trusted local network by operator decision. Never expose an anonymous listener to the internet.[3]

  7. Migrate the 2.0.x legacy options to the listener-specific model

    Replace bare password_file with the password-file plugin, bare acl_file with the acl-file plugin, and per_listener_settings placement with listener-specific options, or upgrade to the current 2.1.x stable line where these are the documented model.[3][1]

  8. TCP fails: investigate the path, bind address, or broker process

    No MQTT diagnosis applies until TCP completes. Confirm the intended broker host and port, the broker process state through the deployment's service control, and the network path and firewall between client and broker. Return here only after TCP completes and the broker answers with an MQTT-level refusal.[5]

  9. Investigate the actual observation

    A TLS handshake failure needs certificate investigation. A connected client with topic problems needs subscription and ACL investigation. A broker-to-broker bridge needs bridge investigation. None of these is a refused MQTT client connection.[5]

  10. Collect a broker refusal evidence packet

    Preserve the installed version, the client command with the negotiated protocol version, the exact exit code, the reached listener block with its authentication bindings, and the broker log lines. Send the sanitized evidence to the operator; no documented branch remains.[5][4]

Detailed diagnosis

Read-only

1. Prove TCP reachability to the broker port

Confirm the client completes TCP to the configured broker host and port. A completed handshake followed by an MQTT refusal keeps this page applicable; a TCP failure exits to network, firewall, or broker-process investigation. Never treat an operating-system connection refusal as an authentication finding.[5]

Read-only

2. Read the CONNACK refusal code

Use the client exit code, which the mosquitto_sub man page defines as the CONNACK reason code on MQTT-level refusal. Under MQTT 3.1.1, 4 means bad username or password and 5 means not authorized; under MQTT v5, consult the documented v5 codes (for example 134 and 135 for the same two conditions) for the protocol version the client negotiated.[5]

Read-only

3. Inspect the listener-specific authentication for the reached listener

Read mosquitto.conf and its included files and identify the exact listener block the client reaches. On 2.1.x, each listener carries its own authentication: listener_allow_anonymous, the mosquitto_password_file plugin (whose password file is generated with mosquitto_passwd and applied per listener with plugin_load and plugin_use), or another plugin. The deprecated bare password_file, acl_file, and per_listener_settings options must not be read as current configuration on 2.1.x.[4][3][6]

Read-only

4. Only on 2.0.x: check the legacy option placement

This step applies solely to brokers still running the 2.0.x line. There, per_listener_settings true makes an auth option apply to the listener currently being configured, so an option placed before or outside the intended listener block silently applies to the wrong listener. On 2.1.x this entire model is deprecated and the step does not apply.[3][1]

Supported scenarios

These observations narrow the next investigation; they do not establish a unique cause.

Nothing accepts TCP on the broker address

When TCP itself fails, no MQTT exchange ever happens and no CONNACK code exists. This is a network, firewall, bind-address, or stopped-broker condition, not an authentication refusal, and it exits this page.[5]

How to check: Confirm the TCP attempt fails before any MQTT response, then investigate the path, the bound address, and the broker process through the deployment's own service control.[5]

The client offers wrong or missing credentials

A 3.1.1 CONNACK 4 (or the v5 bad-username-or-password code) means the broker evaluated credentials and rejected them: the username, the password, or both do not match the credential store bound to the reached listener.[5]

How to check: Confirm the refusal code is the bad-credentials code for the negotiated protocol version, then compare the offered username against the credential store bound to the reached listener.[5]

The listener denies the client without evaluating usable credentials

A 3.1.1 CONNACK 5 (or the v5 not-authorized code) with anonymous or mismatched credentials means the reached listener's policy refuses the client: anonymous access is not allowed there and no usable credential was accepted. On 2.1.x the default denies unauthenticated clients until a listener-specific choice is configured.[5][3]

How to check: Confirm the refusal code is the not-authorized code, then read which authentication the reached listener actually carries: listener_allow_anonymous, a password-file plugin binding, or another plugin.[5][4]

The client reaches a different listener than intended

Under the 2.1 per-listener model, authentication is attached to individual listener blocks, so a client connecting to the wrong port or interface is evaluated against the wrong policy. The credentials can be correct and still be refused.[3]

How to check: Compare the host and port the client actually connects to against the intended listener block and the authentication bound to each listener.[4][3]

On 2.0.x only: an auth option is attached to the wrong listener

On the legacy 2.0.x line, per_listener_settings true scopes an auth option to the listener currently being configured, so placement order decides which listener it protects. This model is deprecated in 2.1 in favour of listener-specific options with removal in 3.0.[3][1]

How to check: Confirm the broker runs 2.0.x, then read the option order relative to the listener blocks to see which listener the option actually protects.[4]

Next actions and procedure boundaries

Potentially disruptive

Bind the intended authentication to the reached listener

On 2.1.x, configure authentication on the exact listener the client reaches: either allow anonymous access narrowly with listener_allow_anonymous, or load the password-file plugin once and apply it to that listener, with credentials created by mosquitto_passwd and readable by the broker user. Applying the change is a deployment- and version-specific operator handoff: determine the documented service and reload behavior for the installed build before applying it, and do not assume the legacy password_file SIGHUP reload semantics carry over to the plugin. Then retest with the same client and credentials.[3][6][4]

mosquitto_passwd <password-file> <username>

Before changing anything

Risk
Changing broker authentication can lock out working clients and automations that share the broker, and an anonymous listener exposed beyond the trusted network admits anyone. Confirm the exact listener block before editing.[3]
Safer check
Record the current listener blocks, the CONNACK code, and which clients currently connect successfully. Confirm the broker release line is 2.1.x so the listener-specific model applies.[3][1]
Expected result
After the change, the refused client connects with its credentials while previously working clients still connect; anonymous clients remain denied wherever the policy requires it.[3]
Backup / recovery access
Preserve the current mosquitto.conf, all included files, and the credential file before editing, so the previous authentication state can be restored.[4]
Rollback
Restore the recorded prior configuration and credential files and return the broker to its previous state through the deployment's documented service control, then re-verify the previously working clients.[4]
Potentially disruptive

On 2.0.x only: migrate deprecated options to the listener-specific model

Where the broker still runs 2.0.x, replace bare password_file with the mosquitto_password_file plugin, bare acl_file with the mosquitto_acl_file plugin, and per_listener_settings placement with listener-specific options such as listener_allow_anonymous, following the official replacement mapping. Prefer upgrading to the current 2.1.x stable line, where these replacements are the documented model, over preserving deprecated options.[3][1]

Before changing anything

Risk
Migrating authentication rewrites how every listener evaluates clients. A mistranslated option can deny all clients at once, including working automations.[3]
Safer check
Confirm the broker runs 2.0.x and map every deprecated option to its documented replacement before editing. Record all currently connecting clients as the regression baseline.[1][3]
Expected result
After migration, each listener enforces the same policy as before under supported options, and the deprecated options are gone from the configuration.[3]
Backup / recovery access
Preserve the full pre-migration configuration and credential files before editing.[4]
Rollback
Restore the recorded prior configuration and return the broker to its previous state through the deployment's documented service control.[4]
Read-only

If TCP fails: investigate the path, bind address, or broker process

A TCP failure means no MQTT diagnosis applies yet. Confirm the client targets the intended broker host and port, confirm the broker process is running through the deployment's service control, and investigate the network path and firewall between them. Return to this page only after TCP completes and the broker answers with an MQTT-level refusal.[5]

Read-only

If the refusal matches no documented branch: preserve the evidence

Record the installed Mosquitto version, the client command with the negotiated protocol version, the exact exit code and any CONNACK text, the reached listener block with its authentication bindings, and the broker log lines for the attempt. Send the sanitized evidence to the operator; the official references describe no procedure for a refusal outside these branches.[5][4]

Warnings and boundaries

Never present an internet-facing anonymous listener as a fix. Anonymous access is only ever scoped to a trusted local network by an explicit operator decision, because anything connecting to that listener can publish and subscribe freely.[3]
Do not use bare password_file, acl_file, or per_listener_settings as the recommended current configuration: on the 2.1.x line they are deprecated with removal in 3.0, and the documented model is the password-file and acl-file plugins with listener-specific options.[1][3]

Sources

Links were reviewed on 2026-09-07. Reachability and automated validation do not replace editorial verification of each claim.

  1. Version 2.1.0 released
    Eclipse Mosquitto · Tier A · accessed 2026-09-07
  2. Version 2.1.2 released
    Eclipse Mosquitto · Tier B · accessed 2026-09-07
  3. Replacing the per_listener_settings option
    Eclipse Mosquitto · Tier A · accessed 2026-09-07
  4. mosquitto.conf man page
    Eclipse Mosquitto · Tier A · accessed 2026-09-07
  5. mosquitto_sub man page
    Eclipse Mosquitto · Tier A · accessed 2026-09-07
  6. Password file Plugin
    Eclipse Mosquitto · Tier A · accessed 2026-09-07