[Devolutions Server] Surface the actual reason behind "Certificate could not be verified"
1 vote
Summary
When Devolutions Server cannot validate a Gateway certificate, it shows a single message — "Certificate could not be verified" — for at least three fundamentally different situations that each require a completely different fix. In our case the dialog appeared with every field blank, while the Gateway log at the same moment contained the precise cause. The information exists; it just never reaches the person looking at the screen.
We lost most of a working day to this, and the same empty dialog appears in other threads on this forum, where it consistently leads people to conclude their certificate is at fault.
What we saw
Devolutions Server displayed:
⚠ Certificate could not be verified Issued To (empty) Issued by (empty) Expires on (empty) Issued On (empty) Thumbprint (empty)
The Devolutions Gateway log, at the same timestamp:
ERROR devolutions_gateway::tls::windows: Failed to resolve TLS certificate error="no usable certificate found in the system store; key acquisition failures: cert[0]: failed to acquire key: Error code 80090016" ERROR devolutions_gateway::listener: handle_https_peer failed error="TLS handshake failed: unexpected error: no server certificate chain resolved"
`0x80090016` is `NTE_BAD_KEYSET`. The Gateway service account had no read permission on the certificate's private key, so no certificate was presented and the handshake never completed. Nothing was wrong with the certificate itself — it is CA-issued, has the correct SANs and the Server Authentication EKU, and is valid until 2029.
Because the dialog said "could not be verified", we spent a long time investigating trust and certificate chains. That was entirely the wrong direction, and the dialog is what pointed us there.
Request 1 — distinguish the failure modes
"Certificate could not be verified" currently covers at least three cases:
| What actually happened | What the user must do --------------------------------------------------------------------------------- | No certificate was presented at all | Fix the Gateway's certificate loading — permissions, store lookup, listener scheme | A certificate was presented, chain incomplete | Add the intermediate certificate | A certificate was presented, not trusted | Install the CA certificate in the trust store
These have nothing in common except the dialog they produce. In particular: **when all fields come back empty, no certificate was presented.** That is not a verification failure, and the dialog should not describe it as one.
Request 2 — name the likely cause
A single additional sentence turns a dead end into a starting point. For example:
> No certificate was presented by the Gateway.
> The Gateway may not have been able to load it. Check the Gateway log at `C:\ProgramData\Devolutions\Gateway`, and verify that the Gateway service account has read access to the certificate's private key.
Request 3 — pass the Gateway's own error text through
The Gateway already produces exactly the right string. A collapsible Details section in the dialog containing the raw error would cover every case, including ones nobody has anticipated, and requires no per-error design work.
The same pattern in Remote Desktop Manager
Worth mentioning because it is the same failure of translation, not a separate complaint. RDM showed "Unable to connect to the recording server." The Gateway had in fact answered — with HTTP 507 and the body `recording storage is not writable`:
WARN devolutions_gateway::api::jrec: Refusing JREC push:
recording storage is not writable
ERROR devolutions_gateway::http: error=507 Insufficient Storage
recording storage is not writable
The cause was that our `RecordingPath` pointed at a drive root, where the default Windows volume ACL lets `BUILTIN\Users` create folders but not files. The connection had succeeded; the storage was rejected. "Unable to connect" is not merely vague here — it describes something that did not happen.
Why this is worth doing
Both problems were permission issues with a one-line fix. Both were diagnosed in under a minute once we read the Gateway log, and both were essentially undiagnosable from the UI alone. Every user who hits the empty certificate dialog will reasonably conclude that their certificate is broken, because that is what the message tells them — and will then open a support case about a certificate that was never the problem.
---
Related request for Devolutions Gateway: validate the TLS certificate at service startup rather than at first handshake.