{"record":{"id":"a528f7a2ed8be491","repo":"mgth/LittleBigMouse","slug":"mqtterror-connack-payload-1","errorCode":null,"errorMessage":"MqttError(connack.Payload[1])","messagePattern":"MqttError\\(connack\\.Payload\\[1\\]\\)","errorType":"exception","errorClass":"UnauthorizedAccessException","httpStatus":null,"severity":"error","filePath":"LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaMqttConnection.cs","lineNumber":88,"sourceCode":"                \"VIDAA rejected TLS. Select the PKCS#12 client certificate extracted from the official app.\", e);\n        }\n\n        _stream = ssl;\n        await WritePacketAsync(BuildConnectPacket(clientId, username, password), cancellationToken)\n            .ConfigureAwait(false);\n        (byte Header, byte[] Payload) connack;\n        try\n        {\n            connack = await ReadPacketAsync(_stream, cancellationToken).ConfigureAwait(false);\n        }\n        catch (IOException e) when (certificates.Count == 0)\n        {\n            throw VidaaCertificate.MissingException(e);\n        }\n        if ((connack.Header >> 4) != 2 || connack.Payload.Length < 2)\n            throw new IOException(\"VIDAA returned an invalid MQTT connection response.\");\n        if (connack.Payload[1] != 0)\n            throw new UnauthorizedAccessException(MqttError(connack.Payload[1]));\n\n        _connected = true;\n        // The caller token limits the handshake only. Once established, MQTT has\n        // its own lifetime so a completed UI command cannot tear down the session.\n        _lifetime = new CancellationTokenSource();\n        _readerTask = ReadLoopAsync(_lifetime.Token);\n        _pingTask = PingLoopAsync(_lifetime.Token);\n    }\n\n    public async Task SubscribeAsync(IEnumerable<string> topics, CancellationToken cancellationToken)\n    {\n        foreach (var topic in topics)\n        {\n            var id = unchecked(++_packetId);\n            if (id == 0) id = unchecked(++_packetId);\n            using var body = new MemoryStream();\n            WriteUInt16(body, id);\n            WriteUtf8(body, topic);","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/mgth/LittleBigMouse/blob/7a42f01d47d99d223b8ee33ba4019af82adf1c48/LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaMqttConnection.cs#L70-L106","documentation":"Thrown in VidaaMqttConnection.ConnectAsync when the TV's CONNACK payload reports a non-zero return code (connack.Payload[1] != 0). Per the MQTT spec, byte 1 of CONNACK is the connection-return code, so this is the TV's MQTT broker explicitly refusing the connection. The code is translated into an UnauthorizedAccessException via MqttError, indicating the reason (e.g. bad credentials, not authorized, identifier rejected).","triggerScenarios":"ConnectAsync (via OpenMqttAsync) receives a valid CONNACK whose second payload byte is non-zero — the broker rejected the CONNECT: wrong username/password, unaccepted clientId, or server-unavailable/ unauthorized return codes.","commonSituations":"Pairing/auth token expired or revoked after TV re-pairing; connecting with a clientId the TV doesn't recognize; TV in a state where remote-control API access is disabled (settings changed, retail mode); firmware update that tightened authentication requirements.","solutions":["Re-pair with the TV / refresh the stored VIDAA credentials (token) and retry.","Check the TV settings: enable the external-control / remote API and ensure it isn't in retail/demo mode.","Verify the clientId and username this plugin uses match what the TV expects; regenerate if firmware changed them.","Read the MqttError message on the exception — it maps the return code to the exact broker refusal reason."],"exampleFix":"// before\nawait connection.OpenMqttAsync(token);\n// after: recover from broker auth rejection by re-authenticating\ntry { await connection.OpenMqttAsync(token); }\ncatch (UnauthorizedAccessException e)\n{ await RePairDeviceAsync(); await connection.OpenMqttAsync(token); }","handlingStrategy":"retry","validationCode":"// Ensure credentials exist and are fresh before connecting\nif (string.IsNullOrEmpty(vidaaToken)) throw new InvalidOperationException(\"No VIDAA pairing token; pair with the TV first.\");","typeGuard":"bool IsConnackAccepted(byte[] payload) => payload.Length >= 2 && payload[1] == 0;","tryCatchPattern":"try { await connection.OpenMqttAsync(token); }\ncatch (UnauthorizedAccessException e)\n{ // broker refused: re-pair / refresh credentials, then retry once }","preventionTips":["Re-pair and refresh the token whenever the TV is factory-reset or re-paired elsewhere","Keep TV remote/external-control API enabled and out of retail mode","Map the CONNACK return code via MqttError to the specific refusal before retrying","Back off between retries to avoid lockouts from repeated bad credentials"],"tags":["mqtt","authentication","connack-refused","iot"],"backgroundTag":"authentication-required","analyzedSha":"7a42f01d47d99d223b8ee33ba4019af82adf1c48","analyzedAt":"2026-09-16T00:35:00.514Z","contentChangedAt":"2026-09-16T00:35:00.514Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}