Skip to content

utils: surface troubleshooting guidance for certificate trust errors#2357

Open
alexweininger wants to merge 5 commits into
mainfrom
alexweininger/cert-trust-error-messaging
Open

utils: surface troubleshooting guidance for certificate trust errors#2357
alexweininger wants to merge 5 commits into
mainfrom
alexweininger/cert-trust-error-messaging

Conversation

@alexweininger

Copy link
Copy Markdown
Member

Problem

When an operation fails because the Node.js extension host cannot build a trusted TLS certificate chain (for example unable to get local issuer certificate / SELF_SIGNED_CERT_IN_CHAIN), the extension shows only the raw OpenSSL error. On developer machines this is almost always a corporate proxy or SSL-inspection appliance whose root CA is not trusted by Node. The fix is documented (NODE_EXTRA_CA_CERTS), but the error itself gives the user no hint that this is the cause or where to look.

Related to microsoft/vscode-azureappservice#2899 and microsoft/vscode-azurefunctions#5124.

Change

  • Adds a shared classifier isCertificateTrustError(parsedError) (utils/src/utils/certificateTrustError.ts) that recognizes the known Node/OpenSSL certificate-chain error codes and their human-readable messages.
  • Wires it into the central handleError path in callWithTelemetryAndErrorHandling. When an error is classified as a certificate trust failure and display is not suppressed, the extension now:
    • appends a short explanatory hint to the error notification and the output channel, and
    • adds a Learn more button that opens the troubleshooting documentation.

Because this lives in the shared @microsoft/vscode-azext-utils error path, every extension that uses callWithTelemetryAndErrorHandling gets the improved guidance automatically, with no per-extension changes.

Scope / design notes

  • Classification is intentionally limited to certificate-chain errors (codes + known OpenSSL strings) to avoid false positives on unrelated network failures. Broad proxy-connection classification is out of scope.
  • No public API change: the classifier is internal and unit-tested via direct import; index.d.ts is untouched.
  • The troubleshooting link points at the canonical Resource Groups README troubleshooting section that the other extensions' READMEs already link to.

Validation

  • tsc -p ./ --noEmit clean, eslint --max-warnings 0 clean.
  • vscode-test: 249 passing, including 5 new tests for the classifier.

Operations that fail because the Node extension host cannot build a trusted TLS
certificate chain (for example "unable to get local issuer certificate") currently
show only the raw, cryptic error. On developer machines this is almost always a
corporate proxy or SSL-inspection appliance whose root CA is not trusted by Node,
and the fix is documented (NODE_EXTRA_CA_CERTS), but the error gives no hint.

Add a shared classifier isCertificateTrustError() and wire it into the central
handleError path in callWithTelemetryAndErrorHandling, so every extension that uses
it automatically gets: a short explanatory hint appended to the notification and
output channel, plus a "Learn more" button that opens the troubleshooting docs.

Classification is limited to known Node/OpenSSL certificate error codes and their
human-readable messages to avoid false positives on unrelated network errors.

Related to microsoft/vscode-azureappservice#2899
Related to microsoft/vscode-azurefunctions#5124

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 1, 2026 17:10
@alexweininger alexweininger requested a review from a team as a code owner July 1, 2026 17:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the shared @microsoft/vscode-azext-utils error-handling path by detecting TLS certificate trust-chain failures and surfacing actionable troubleshooting guidance (hint text + output channel details + “Learn more” link) for extensions using callWithTelemetryAndErrorHandling.

Changes:

  • Added isCertificateTrustError(parsedError) and a canonical troubleshooting URL constant for certificate trust failures.
  • Integrated certificate-trust detection into handleError to append guidance to notifications/output and provide a “Learn more” button.
  • Added unit tests covering common Node/OpenSSL certificate-chain error codes and message fragments.
Show a summary per file
File Description
utils/test/certificateTrustError.test.ts Adds unit tests validating the certificate trust error classifier behavior.
utils/src/utils/certificateTrustError.ts Introduces the certificate trust error classifier and troubleshooting link constant.
utils/src/callWithTelemetryAndErrorHandling.ts Wires the classifier into central error handling to show guidance and a “Learn more” button.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment thread utils/src/utils/certificateTrustError.ts

if (!context.errorHandling.suppressDisplay) {
const isCertError: boolean = isCertificateTrustError(unMaskedErrorData);
const certHint: string = l10n.t('This can happen behind a corporate proxy or SSL-inspection appliance whose certificate authority is not trusted by VS Code. See the troubleshooting steps for how to trust it.');

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, reworded in 8a109f4 to attribute the failure to the Node.js extension host being unable to build a trusted chain (rather than 'VS Code'), and to mention NODE_EXTRA_CA_CERTS.

alexweininger and others added 3 commits July 1, 2026 13:19
Fixes CI lint failure (@typescript-eslint/no-unnecessary-type-assertion): the
object literal already satisfies IParsedError, so the cast is redundant. Build
the base as a typed const and spread instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove 'certificate has expired' from the classifier: an expired leaf/server
  cert (or bad local clock) is not an untrusted corporate root CA, so including
  it risks false positives that surface proxy/CA guidance when it does not apply.
- Reword the hint to attribute the failure to the Node.js extension host being
  unable to build a trusted chain (not 'VS Code'), and mention NODE_EXTRA_CA_CERTS.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Completeness: also match the non-_LOCALLY issuer-cert error code and its
human-readable message, which some OpenSSL/Node versions surface.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Default troubleshooting documentation for certificate trust failures. All Azure extensions
* link their README troubleshooting sections to this canonical location.
*/
export const certificateTroubleshootingLink: string = 'https://github.com/microsoft/vscode-azureresourcegroups/blob/main/README.md#troubleshooting';

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

turn this into aka.ms link

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here's the aka.ms link I created: aka.ms/AA11ri61

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 6cec7b3 — certificateTroubleshootingLink now points at https://aka.ms/AA11ri61 instead of the branch-specific README URL, so it survives README moves/renames. Updated the doc comment to match.

Point certificateTroubleshootingLink at the stable aka.ms/AA11ri61 redirect
instead of a branch-specific GitHub README URL, so it survives README moves.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants