Summary
Certificates imported via Edit -> SSL Certificates -> Import Certificates are only trusted by the Node networking stack. When the proxy source is set to System proxy, Storage Explorer routes requests through the Electron net (Chromium) stack instead, which does not consult imported certs. The result is a confusing ERR_CERT_AUTHORITY_INVALID / "Electron Net Error" against an endpoint whose certificate the user has already imported -- most visibly when working with an HTTPS Azurite emulator.
The proxy setting is effectively a hidden networking-stack switch, and the two stacks have different certificate-trust sources. This is especially painful on Linux, where the Electron/Chromium stack trusts the per-user NSS database (~/.pki/nssdb) rather than the OS CA bundle, so neither the in-app import nor a system-store install makes the cert take effect on that stack.
Environment
- Storage Explorer 1.45.0 (repros structurally on prior versions)
- Observed on Linux (snap), but the stack-selection logic is cross-platform
- HTTPS Azurite container (self-signed cert,
IP:127.0.0.1)
Steps to reproduce
- Start Azurite over HTTPS with a self-signed cert.
- In Storage Explorer, Edit -> SSL Certificates -> Import Certificates and import the cert. Restart.
- Set proxy source = System proxy (
application.proxy.source = "systemProxy").
- Attach the local emulator and expand Blob Containers / Queues.
Expected: the node lists children (the cert was imported).
Actual: Unable to retrieve child resources -- ProducerError: Electron Net Error / net::ERR_CERT_AUTHORITY_INVALID.
Switching proxy source to Do not use proxy (none) makes it work immediately -- not because a proxy was bypassed, but because the request moves back onto the Node stack that trusts the imported cert.
Root cause
src/Standalone/app/main/Net/NetProvider.ts selects the networking stack purely from the proxy source:
const result = await makeRequest(
args.options,
process.env.STG_EXP_PROXY_SRC === "systemProxy" ? "electron" : "node",
true);
systemProxy -> ElectronRequest (Electron net / Chromium). Trust source: OS store on Windows/macOS, NSS db on Linux. Does not see in-app imported certs.
- Every other source (
none default, environmentVariable, appConfig) -> NodeRequest (Node https). Trust source: syswide-cas over userData/certs, i.e. the in-app imported certs (SslCertificateManagerMain._loadTrustedCerts).
Imported certs are wired only into the Node stack, so they silently do nothing whenever the effective stack is Electron.
The asymmetric auto-recovery in the same file makes it worse. maybeRetryRequest only retries node -> electron:
if (requestUsed === "node" && shouldRetry) { // cert/notfound error on node -> retry via electron
return await retryFailedRequestWithElectron(...);
}
and on success it persists the switch:
await ConfigurationManager.setConfiguration("application.proxy.source", "systemProxy");
There is no electron -> node fallback. So a user who hits a transient cert error on the Node stack can be auto-moved to systemProxy (the Electron stack), after which their imported cert no longer applies and there is no path back except manually changing the proxy source.
Impact
- Imported certificates appear to "not work" for any user on System proxy, with an error that points at cert trust rather than the real cause (stack selection).
- The auto-manage-proxy feature can strand users on the exact stack that ignores their imported cert.
- On Linux the only ways to satisfy the Electron stack are adding the cert to the snap/user NSS db (
certutil -d sql:...nssdb -A -t "C,," ...) or launching with --ignore-certificate-errors -- neither is discoverable, and NSS trust is per snap-revision so it is lost on update.
Suggested directions
- Feed imported certs into the Electron stack too (e.g.
session.setCertificateVerifyProc / a verify handler that trusts userData/certs), so import works regardless of proxy source.
- Add an electron -> node cert-error fallback to mirror the existing node -> electron retry, and/or avoid auto-switching a user onto
systemProxy when doing so would drop imported-cert trust.
- At minimum, surface a clearer message distinguishing "cert not trusted by the active networking stack" from a genuine authority failure, and document the Linux NSS requirement.
Related
Summary
Certificates imported via Edit -> SSL Certificates -> Import Certificates are only trusted by the Node networking stack. When the proxy source is set to System proxy, Storage Explorer routes requests through the Electron
net(Chromium) stack instead, which does not consult imported certs. The result is a confusingERR_CERT_AUTHORITY_INVALID/ "Electron Net Error" against an endpoint whose certificate the user has already imported -- most visibly when working with an HTTPS Azurite emulator.The proxy setting is effectively a hidden networking-stack switch, and the two stacks have different certificate-trust sources. This is especially painful on Linux, where the Electron/Chromium stack trusts the per-user NSS database (
~/.pki/nssdb) rather than the OS CA bundle, so neither the in-app import nor a system-store install makes the cert take effect on that stack.Environment
IP:127.0.0.1)Steps to reproduce
application.proxy.source = "systemProxy").Expected: the node lists children (the cert was imported).
Actual:
Unable to retrieve child resources -- ProducerError: Electron Net Error / net::ERR_CERT_AUTHORITY_INVALID.Switching proxy source to Do not use proxy (
none) makes it work immediately -- not because a proxy was bypassed, but because the request moves back onto the Node stack that trusts the imported cert.Root cause
src/Standalone/app/main/Net/NetProvider.tsselects the networking stack purely from the proxy source:systemProxy->ElectronRequest(Electronnet/ Chromium). Trust source: OS store on Windows/macOS, NSS db on Linux. Does not see in-app imported certs.nonedefault,environmentVariable,appConfig) ->NodeRequest(Nodehttps). Trust source:syswide-casoveruserData/certs, i.e. the in-app imported certs (SslCertificateManagerMain._loadTrustedCerts).Imported certs are wired only into the Node stack, so they silently do nothing whenever the effective stack is Electron.
The asymmetric auto-recovery in the same file makes it worse.
maybeRetryRequestonly retries node -> electron:and on success it persists the switch:
There is no electron -> node fallback. So a user who hits a transient cert error on the Node stack can be auto-moved to
systemProxy(the Electron stack), after which their imported cert no longer applies and there is no path back except manually changing the proxy source.Impact
certutil -d sql:...nssdb -A -t "C,," ...) or launching with--ignore-certificate-errors-- neither is discoverable, and NSS trust is per snap-revision so it is lost on update.Suggested directions
session.setCertificateVerifyProc/ a verify handler that trustsuserData/certs), so import works regardless of proxy source.systemProxywhen doing so would drop imported-cert trust.Related