mgth/LittleBigMouse · error · UnauthorizedAccessException
MqttError(connack.Payload[1])
Error message
MqttError(connack.Payload[1])
What it means
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).
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.
Example fix
// before
await connection.OpenMqttAsync(token);
// after: recover from broker auth rejection by re-authenticating
try { await connection.OpenMqttAsync(token); }
catch (UnauthorizedAccessException e)
{ await RePairDeviceAsync(); await connection.OpenMqttAsync(token); } Defensive patterns
Strategy: retry
Validate before calling
// Ensure credentials exist and are fresh before connecting
if (string.IsNullOrEmpty(vidaaToken)) throw new InvalidOperationException("No VIDAA pairing token; pair with the TV first."); Type guard
bool IsConnackAccepted(byte[] payload) => payload.Length >= 2 && payload[1] == 0;
Try / catch
try { await connection.OpenMqttAsync(token); }
catch (UnauthorizedAccessException e)
{ // broker refused: re-pair / refresh credentials, then retry once } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- VIDAA returned an invalid MQTT connection response.
- The VIDAA MQTT connection is closed.
- Malformed MQTT remaining length.
- VIDAA closed the MQTT connection.
- VIDAA rejected every authentication variant for protocol
AI-assisted analysis of mgth/LittleBigMouse@7a42f01d47 (2026-09-16).
Data as JSON: /api/errors/a528f7a2ed8be491.
Report an issue: GitHub.
Appendix: source
Thrown at LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaMqttConnection.cs:88
"VIDAA rejected TLS. Select the PKCS#12 client certificate extracted from the official app.", e);
}
_stream = ssl;
await WritePacketAsync(BuildConnectPacket(clientId, username, password), cancellationToken)
.ConfigureAwait(false);
(byte Header, byte[] Payload) connack;
try
{
connack = await ReadPacketAsync(_stream, cancellationToken).ConfigureAwait(false);
}
catch (IOException e) when (certificates.Count == 0)
{
throw VidaaCertificate.MissingException(e);
}
if ((connack.Header >> 4) != 2 || connack.Payload.Length < 2)
throw new IOException("VIDAA returned an invalid MQTT connection response.");
if (connack.Payload[1] != 0)
throw new UnauthorizedAccessException(MqttError(connack.Payload[1]));
_connected = true;
// The caller token limits the handshake only. Once established, MQTT has
// its own lifetime so a completed UI command cannot tear down the session.
_lifetime = new CancellationTokenSource();
_readerTask = ReadLoopAsync(_lifetime.Token);
_pingTask = PingLoopAsync(_lifetime.Token);
}
public async Task SubscribeAsync(IEnumerable<string> topics, CancellationToken cancellationToken)
{
foreach (var topic in topics)
{
var id = unchecked(++_packetId);
if (id == 0) id = unchecked(++_packetId);
using var body = new MemoryStream();
WriteUInt16(body, id);
WriteUtf8(body, topic);View on GitHub (pinned to 7a42f01d47)