mgth/LittleBigMouse · error · FileNotFoundException

The VIDAA client certificate was not found.

Error message

The VIDAA client certificate was not found.

What it means

VidaaMqttConnection.ConnectAsync builds the TLS client certificate collection from a configured PKCS#12 file path. If certificatePath is non-empty but the file does not exist on disk, it throws this FileNotFoundException with the path as the fileName parameter. The library refuses to continue rather than attempting the TLS handshake without the configured client certificate.

Solutions

  1. Verify the file at certificatePath exists (File.Exists) and fix the configured path to point at the actual .p12/.pfx file.
  2. Re-extract the PKCS#12 client certificate from the official Hisense VIDAA app and save it to the configured location.
  3. If packaging/deploying, ensure the certificate file is copied with the app (or volume-mounted in containers) and use absolute paths.
  4. Run the app from a working directory consistent with any relative configured paths, or switch config to absolute paths.

Example fix

// before
await connection.OpenMqttAsync(certPath: "vidaajson/client.p12", password);

// after
if (!File.Exists(certPath))
    throw new InvalidOperationException($"Set the VIDAA certificate path to an existing PKCS#12 file (current: {Path.GetFullPath(certPath)}).");
await connection.OpenMqttAsync(certPath: Path.GetFullPath(certPath), password);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(certificatePath) || !File.Exists(certificatePath))
    throw new InvalidOperationException($"VIDAA client certificate not found at '{certificatePath}'. Extract the PKCS#12 from the official app and configure its path.");

Type guard

static bool HasCertificateFile(string? path) =>
    !string.IsNullOrWhiteSpace(path) && File.Exists(path);

Try / catch

try
{
    await connection.OpenMqttAsync(certificatePath, password, ct);
}
catch (FileNotFoundException ex) when (ex.FileName == certificatePath)
{
    // prompt user to locate or re-extract the .p12 client certificate
}

Prevention

When it happens

Trigger: Calling OpenMqttAsync/ConnectAsync with a certificatePath pointing to a missing file: path never created, user deleted or moved the .p12/.pfx, wrong path in config, relative path resolved against an unexpected working directory, app running on a different machine or container without the certificate.

Common situations: Certificate extracted from the official VIDAA app but stored elsewhere than configured; fresh install/machine migration lost the file; Docker volume not mounted; case-sensitivity or typo in the configured path; relative path broken after working-directory change.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of mgth/LittleBigMouse@7a42f01d47 (2026-09-16). Data as JSON: /api/errors/a50e816211c19612. Report an issue: GitHub.

Appendix: source

Thrown at LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaMqttConnection.cs:48

        string username,
        string password,
        string certificatePath,
        string certificatePassword,
        CancellationToken cancellationToken)
    {
        await DisposeConnectionAsync().ConfigureAwait(false);
        _tcpClient = new TcpClient(AddressFamily.InterNetwork);
        await _tcpClient.ConnectAsync(host, port, cancellationToken).ConfigureAwait(false);

        var ssl = new SslStream(
            _tcpClient.GetStream(),
            leaveInnerStreamOpen: false,
            (_, _, _, _) => true);
        var certificates = new X509CertificateCollection();
        if (!string.IsNullOrWhiteSpace(certificatePath))
        {
            if (!File.Exists(certificatePath))
                throw new FileNotFoundException("The VIDAA client certificate was not found.", certificatePath);
            certificates.Add(X509CertificateLoader.LoadPkcs12FromFile(
                certificatePath, certificatePassword,
                X509KeyStorageFlags.EphemeralKeySet | X509KeyStorageFlags.Exportable));
        }

        try
        {
            await ssl.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
            {
                TargetHost = host,
                ClientCertificates = certificates,
                // Several VIDAA U6 brokers advertise newer TLS but abort encrypted
                // application data after negotiating it. The official Android client
                // uses TLS 1.2 for this MQTT channel.
                EnabledSslProtocols = SslProtocols.Tls12,
                CertificateRevocationCheckMode = X509RevocationMode.NoCheck,
            }, cancellationToken).ConfigureAwait(false);
        }

View on GitHub (pinned to 7a42f01d47)