{"record":{"id":"a50e816211c19612","repo":"mgth/LittleBigMouse","slug":"the-vidaa-client-certificate-was-not-found","errorCode":null,"errorMessage":"The VIDAA client certificate was not found.","messagePattern":"The VIDAA client certificate was not found\\.","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaMqttConnection.cs","lineNumber":48,"sourceCode":"        string username,\n        string password,\n        string certificatePath,\n        string certificatePassword,\n        CancellationToken cancellationToken)\n    {\n        await DisposeConnectionAsync().ConfigureAwait(false);\n        _tcpClient = new TcpClient(AddressFamily.InterNetwork);\n        await _tcpClient.ConnectAsync(host, port, cancellationToken).ConfigureAwait(false);\n\n        var ssl = new SslStream(\n            _tcpClient.GetStream(),\n            leaveInnerStreamOpen: false,\n            (_, _, _, _) => true);\n        var certificates = new X509CertificateCollection();\n        if (!string.IsNullOrWhiteSpace(certificatePath))\n        {\n            if (!File.Exists(certificatePath))\n                throw new FileNotFoundException(\"The VIDAA client certificate was not found.\", certificatePath);\n            certificates.Add(X509CertificateLoader.LoadPkcs12FromFile(\n                certificatePath, certificatePassword,\n                X509KeyStorageFlags.EphemeralKeySet | X509KeyStorageFlags.Exportable));\n        }\n\n        try\n        {\n            await ssl.AuthenticateAsClientAsync(new SslClientAuthenticationOptions\n            {\n                TargetHost = host,\n                ClientCertificates = certificates,\n                // Several VIDAA U6 brokers advertise newer TLS but abort encrypted\n                // application data after negotiating it. The official Android client\n                // uses TLS 1.2 for this MQTT channel.\n                EnabledSslProtocols = SslProtocols.Tls12,\n                CertificateRevocationCheckMode = X509RevocationMode.NoCheck,\n            }, cancellationToken).ConfigureAwait(false);\n        }","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/mgth/LittleBigMouse/blob/7a42f01d47d99d223b8ee33ba4019af82adf1c48/LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaMqttConnection.cs#L30-L66","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the file at certificatePath exists (File.Exists) and fix the configured path to point at the actual .p12/.pfx file.","Re-extract the PKCS#12 client certificate from the official Hisense VIDAA app and save it to the configured location.","If packaging/deploying, ensure the certificate file is copied with the app (or volume-mounted in containers) and use absolute paths.","Run the app from a working directory consistent with any relative configured paths, or switch config to absolute paths."],"exampleFix":"// before\nawait connection.OpenMqttAsync(certPath: \"vidaajson/client.p12\", password);\n\n// after\nif (!File.Exists(certPath))\n    throw new InvalidOperationException($\"Set the VIDAA certificate path to an existing PKCS#12 file (current: {Path.GetFullPath(certPath)}).\");\nawait connection.OpenMqttAsync(certPath: Path.GetFullPath(certPath), password);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(certificatePath) || !File.Exists(certificatePath))\n    throw new InvalidOperationException($\"VIDAA client certificate not found at '{certificatePath}'. Extract the PKCS#12 from the official app and configure its path.\");","typeGuard":"static bool HasCertificateFile(string? path) =>\n    !string.IsNullOrWhiteSpace(path) && File.Exists(path);","tryCatchPattern":"try\n{\n    await connection.OpenMqttAsync(certificatePath, password, ct);\n}\ncatch (FileNotFoundException ex) when (ex.FileName == certificatePath)\n{\n    // prompt user to locate or re-extract the .p12 client certificate\n}","preventionTips":["Store the certificate in a stable, absolute path and verify File.Exists at startup.","Include the .p12 in app deployment or mount it in containers.","Re-extract the certificate after reinstalls or machine migrations."],"tags":["csharp","tls","certificate","file-not-found"],"backgroundTag":"file-not-found","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"}