How do I debug Mosquitto broker?

I am trying to understand why a simple micropython sensor setup on a pico2_w as client has stopped being able to connect and publish to my mosquitto broker on homeassistant OS running on a raspberry pi4. I have tried to debug, and it seems like the broker is closing connection / disconnecting / not responding the way it should, but the debug log only shows:

2025-03-12 20:33:47: New connection from 192.168.86.8:59092 on port 1883.
2025-03-12 20:33:47: Client <unknown> disconnected due to protocol error.

I have used MQTT Explorer and the exact same connection details and it will connect (I even set the same client ID the pico script was using that mosquitto broker calls unknown)

2025-03-12 20:46:27: New connection from 192.168.86.9:54254 on port 1883.
2025-03-12 20:46:27: New client connected from 192.168.86.9:54254 as 2c:cf:67:ba:f2:87 (p2, c1, k60, u'pico2').

Here is my connect function that I call, (and I want to note that this all fails on the connection, not publishing of data as we never get that far):

def connect_mqtt():
    print("Connecting to MQTT")
    for x in range(2):

        try:
            print("Attempting connection")
            
            client = MQTTClient("2c:cf:67:ba:f2:87",MQTT_BROKER ,user=MQTT_USER, password=MQTT_PASSWORD)
            print("Setting connection data... ")
            client.connect()
            print("Connected to MQTT Broker")
            return client
        except OSError as e:
            print(f"MQTT Connection failed: {e}, retrying...")
            time.sleep(3)
        raise RuntimeError("Failed to connect to MQTT Broker after multiple attempts.")

I pulled data from the umqtt package I was using into the script to also help with debugging (I placed the print(“#”) throughout to try and figure out where things are going awry:

class MQTTException(Exception):
    pass

class MQTTClient:
    print("a")
    def __init__(self, client_id, server, port=1883, user=None, password=None, keepalive=60):
        print("b")
        self.client_id = client_id
        self.server = server
        self.port = port
        self.user = user
        self.password = password
        self.keepalive = keepalive
        self.sock = None
        print("c")

    def connect(self):
        """Connects to the MQTT broker."""
        print("entered connect function")
        self.sock = socket.socket()
        print("1")
        addr = socket.getaddrinfo(self.server, self.port)[0][-1]
        print("2")
        self.sock.connect(addr)
        print("3")
        
        # MQTT Connect Packet
        msg = bytearray(b"\x10\0\0\0\0\0")
        print("4")
        msg[1] = 10 + len(self.client_id) + (2 + len(self.user) if self.user else 0) + (2 + len(self.password) if self.password else 0)
        print("5")
        msg.extend(b"\x00\x04MQTT\x04\x02")  # MQTT protocol and version
        print("6")
        msg.extend(struct.pack("!H", self.keepalive))
        print(7)
        msg.extend(struct.pack("!H", len(self.client_id)) + self.client_id.encode())
        print("8")

        if self.user:
            print("9")
            msg.extend(struct.pack("!H", len(self.user)) + self.user.encode())
            print("10")
        if self.password:
            print("11")
            msg.extend(struct.pack("!H", len(self.password)) + self.password.encode())
            print("12")

        self.sock.send(msg)
        print("13")
        
        resp = self.sock.recv(4)
        print("14")
        if resp[0] != 0x20 or resp[1] != 0x02 or resp[3] != 0x00:
            print("15")
            raise MQTTException("MQTT connection failed")
        print("16")

    def publish(self, topic, msg):
        """Publishes a message to a topic."""
        pkt = bytearray(b"\x30\0")
        pkt.extend(struct.pack("!H", len(topic)) + topic.encode() + msg.encode())
        pkt[1] = len(pkt) - 2  # Set remaining length
        self.sock.send(pkt)

    def disconnect(self):
        """Disconnect from the MQTT broker."""
        if self.sock:
            self.sock.send(b"\xE0\x00")  # MQTT DISCONNECT Packet
            self.sock.close()
            self.sock = None

Finally when I run the script here is my output

a
Connecting to Wi-Fi...
Connected to Wi-Fi: ('192.168.86.8', '255.255.255.0', '192.168.86.1', '192.168.86.1')
Connecting to MQTT
Attempting connection
b
c
Setting connection data... 
entered connect function
1
2
3
4
5
6
7
8
9
10
11
12
13
MQTT Connection failed: [Errno 104] ECONNRESET, retrying...
Traceback (most recent call last):
  File "<stdin>", line 187, in <module>
  File "<stdin>", line 133, in connect_mqtt
RuntimeError: Failed to connect to MQTT Broker after multiple attempts.

it seems resp = self.sock.recv(4) is the line that is failing based on the highest print message before erroring out.

I am open to any and all ideas, happy to run a different library, I just want to get this working so I can start collecting data.

Long shot, but try removing the colons from the client ID.

Hello mcunkelman

My suggestion…
In your code, force it to MQTT 3.1.1. If that don’t work try 5 or 3. It is protocol complaining and at this point, without forcing it, you don’t know what protocol you are using. Mosquitto should be able to handle them all, but there was an update not that long ago so it could be broken for one of the protocols.

I did see someone earlier in the week with the broker complaining the same way with a not common client.

Can you elaborate on how I would do that? Is that just setting the port to 1883 in the MQTTClient call?

Good suggestion but did not help.