Skip to content

Fix DevTunnel health check for auto-selected regions - #19230

Open
Vladyslav Danilchuk (Vladipz) wants to merge 3 commits into
microsoft:mainfrom
Vladipz:fix/devtunnel-qualified-id-healthcheck
Open

Fix DevTunnel health check for auto-selected regions#19230
Vladyslav Danilchuk (Vladipz) wants to merge 3 commits into
microsoft:mainfrom
Vladipz:fix/devtunnel-qualified-id-healthcheck

Conversation

@Vladipz

Copy link
Copy Markdown

Description

Fixes #18790

When a DevTunnel region is selected automatically, devtunnel show resolves
the bare tunnel ID and returns a cluster-qualified ID. Per-port access queries
require that qualified form.

Use the returned tunnel ID for tunnel and port access queries.

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
  • Did you add public API?
    • No
  • Does the change make any security assumptions or guarantees?
    • No
Copilot AI balanced review requested due to automatic review settings August 11, 2026 11:11

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 19230

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 19230"
@github-actions github-actions Bot added the area-integrations Issues pertaining to Aspire Integrations packages label Aug 11, 2026
@Vladipz

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@cpizzato

Copy link
Copy Markdown

I'm also suffering with this issue and this fix might solve it. However, sharing two things that might be relevant here:

  • DevTunnelOptions.Region was added in #14112, not yet updated on AddDevTunnelForPolyglot #19495.
    However the thing is, what would happen when a DevTunnel region is selected automatically, but the region was specified by the user?

  • https://github.com/microsoft/dev-tunnels also has an issue opened around the auto-select behavior #642

@Vladipz

Copy link
Copy Markdown
Author

I'm also suffering with this issue and this fix might solve it. However, sharing two things that might be relevant here:

  • DevTunnelOptions.Region was added in #14112, not yet updated on AddDevTunnelForPolyglot #19495.
    However the thing is, what would happen when a DevTunnel region is selected automatically, but the region was specified by the user?
  • https://github.com/microsoft/dev-tunnels also has an issue opened around the auto-select behavior #642

Thanks, this is helpful context.

Explicitly setting DevTunnelOptions.Region is a useful workaround for C# AppHosts when a stable cluster and URL are required. However, I do not think it should be required for the health check to work: users should be able to rely on automatic region selection.

This change addresses that case by using the cluster-qualified tunnel ID returned by devtunnel show for subsequent access queries. Therefore it should work both when the region is auto-selected and when it is explicitly specified.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Found one qualified-ID compatibility gap in the startup path.

@DamianEdwards

Copy link
Copy Markdown
Member

PR #19230 Testing Report

PR information

  • Title: Fix DevTunnel health check for auto-selected regions
  • Head commit: 2a21bc53cfb0e5097845f5afbb4eae0c5cf5e942
  • Tested package: Aspire.Hosting.DevTunnels.13.6.0-pr.19230.g2a21bc53.nupkg
  • Dev Tunnel CLI: 1.0.2030+fc9273aa0f
  • Tested at: 2026-08-31

Artifact verification

The PR's common built-nugets artifact was downloaded from workflow run
31485524110. The package version embeds the PR head short SHA (g2a21bc53),
and the running AppHost reported
TUNNEL_SERVICE_USER_AGENT=Aspire.DevTunnels/13.6.0-pr.19230.g2a21bc53.

The normal Windows dogfood installation could not be used because the workflow
run is still marked in_progress and has not published
cli-native-archives-win-x64 or built-nugets-for-win-x64. Testing therefore
used the PR's common NuGet artifact with the installed Aspire CLI 13.5.2.

Behavior verification

Current behavior

A disposable tunnel created with an unqualified ID returned a qualified ID from
devtunnel create. Immediately afterward:

  • devtunnel access list <bare-id> -p <port> failed with Not Found.
  • devtunnel access list <qualified-id> -p <port> succeeded.

The bare-ID query later succeeded after propagation for a tunnel in the account's
home cluster. A tunnel created in another cluster continued to reproduce the
bare-ID access failure while the qualified-ID query succeeded. This confirms the
reported routing behavior and explains why it is permanent when the selected
cluster differs from the account's home cluster.

Regression test

The new
DevTunnelHealthCheck_WithAutoSelectedRegion_UsesReturnedTunnelIdForAccessOperations
test:

  • Passed with the PR implementation.
  • Failed when the two production calls were temporarily restored to the base
    implementation. The failure showed GetAccessAsync receiving mytunnel
    instead of mytunnel.eun1.

PR package end-to-end

Two fresh file-based AppHosts used the PR package:

Scenario Tunnel Port Public endpoint
Auto-selected region Healthy Running/Healthy HTTP 200
Explicit WestUs2 region Healthy Running/Healthy HTTP 200

The complete Aspire.Hosting.DevTunnels.Tests project passed: 39 tests, 0
failures.

Review finding

  1. The related per-port startup path still uses the bare ID for supported older Dev Tunnel CLI versions.
    OnBeforeResourceStarted receives the qualified ID from
    CreateTunnelAsync but discards it, then uses
    DevTunnelResource.ResolvedTunnelId for per-port create and delete
    operations. With no explicit region, that value is bare. Issue DevTunnel resource always reports Unhealthy due to 'devtunnel access list <id> -p <port>' failing to resolve bare tunnel id #18790
    includes a deterministic report that Dev Tunnel CLI 1.0.1972 fails
    port create <bare-id> -p <port> across clusters. Aspire currently accepts
    versions as old as 1.0.1435. The latest CLI used here no longer reproduced
    the create/delete failure, but the supported older path remains broken.
    Preserve the CreateTunnelAsync result for all subsequent per-port
    operations, or raise the minimum supported CLI version and add coverage for
    the startup flow.

Other observations

  • The PR artifact showed healthy DevTunnel port resources with no Dashboard/MCP
    URLs. This was caused by the PR branch being 209 commits behind current
    main, not by this change. PR Fix DevTunnel endpoint URL publication #19590 fixed it on main, PR [release/13.5] Fix DevTunnel endpoint URL publication #19625 backported
    it to release/13.5, and a 13.5.3 control run exposed both expected URLs.
  • No additional failure was reproduced with the latest Dev Tunnel CLI: bare-ID
    port create/delete worked even for a tunnel in another cluster. Only the
    per-port access query still required the qualified ID.

Result

The health-check change is correct and fixes the claimed access-query failure,
but the PR does not cover the same qualified-ID requirement in all Aspire
startup operations supported by its current minimum Dev Tunnel CLI version.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Copilot AI review requested due to automatic review settings September 1, 2026 08:25

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Vladipz

Copy link
Copy Markdown
Author

PR #19230 Testing Report

PR information

  • Title: Fix DevTunnel health check for auto-selected regions
  • Head commit: 2a21bc53cfb0e5097845f5afbb4eae0c5cf5e942
  • Tested package: Aspire.Hosting.DevTunnels.13.6.0-pr.19230.g2a21bc53.nupkg
  • Dev Tunnel CLI: 1.0.2030+fc9273aa0f
  • Tested at: 2026-08-31

Artifact verification

The PR's common built-nugets artifact was downloaded from workflow run 31485524110. The package version embeds the PR head short SHA (g2a21bc53), and the running AppHost reported TUNNEL_SERVICE_USER_AGENT=Aspire.DevTunnels/13.6.0-pr.19230.g2a21bc53.

The normal Windows dogfood installation could not be used because the workflow run is still marked in_progress and has not published cli-native-archives-win-x64 or built-nugets-for-win-x64. Testing therefore used the PR's common NuGet artifact with the installed Aspire CLI 13.5.2.

Behavior verification

Current behavior

A disposable tunnel created with an unqualified ID returned a qualified ID from devtunnel create. Immediately afterward:

  • devtunnel access list <bare-id> -p <port> failed with Not Found.
  • devtunnel access list <qualified-id> -p <port> succeeded.

The bare-ID query later succeeded after propagation for a tunnel in the account's home cluster. A tunnel created in another cluster continued to reproduce the bare-ID access failure while the qualified-ID query succeeded. This confirms the reported routing behavior and explains why it is permanent when the selected cluster differs from the account's home cluster.

Regression test

The new DevTunnelHealthCheck_WithAutoSelectedRegion_UsesReturnedTunnelIdForAccessOperations test:

  • Passed with the PR implementation.
  • Failed when the two production calls were temporarily restored to the base
    implementation. The failure showed GetAccessAsync receiving mytunnel
    instead of mytunnel.eun1.

PR package end-to-end

Two fresh file-based AppHosts used the PR package:

Scenario Tunnel Port Public endpoint
Auto-selected region Healthy Running/Healthy HTTP 200
Explicit WestUs2 region Healthy Running/Healthy HTTP 200
The complete Aspire.Hosting.DevTunnels.Tests project passed: 39 tests, 0 failures.

Review finding

  1. The related per-port startup path still uses the bare ID for supported older Dev Tunnel CLI versions.
    OnBeforeResourceStarted receives the qualified ID from
    CreateTunnelAsync but discards it, then uses
    DevTunnelResource.ResolvedTunnelId for per-port create and delete
    operations. With no explicit region, that value is bare. Issue DevTunnel resource always reports Unhealthy due to 'devtunnel access list -p ' failing to resolve bare tunnel id #18790
    includes a deterministic report that Dev Tunnel CLI 1.0.1972 fails
    port create <bare-id> -p <port> across clusters. Aspire currently accepts
    versions as old as 1.0.1435. The latest CLI used here no longer reproduced
    the create/delete failure, but the supported older path remains broken.
    Preserve the CreateTunnelAsync result for all subsequent per-port
    operations, or raise the minimum supported CLI version and add coverage for
    the startup flow.

Other observations

  • The PR artifact showed healthy DevTunnel port resources with no Dashboard/MCP
    URLs. This was caused by the PR branch being 209 commits behind current
    main, not by this change. PR Fix DevTunnel endpoint URL publication #19590 fixed it on main, PR [release/13.5] Fix DevTunnel endpoint URL publication #19625 backported
    it to release/13.5, and a 13.5.3 control run exposed both expected URLs.
  • No additional failure was reproduced with the latest Dev Tunnel CLI: bare-ID
    port create/delete worked even for a tunnel in another cluster. Only the
    per-port access query still required the qualified ID.

Result

The health-check change is correct and fixes the claimed access-query failure, but the PR does not cover the same qualified-ID requirement in all Aspire startup operations supported by its current minimum Dev Tunnel CLI version.

Thanks, this makes sense. I preserved the cluster-qualified ID returned by CreateTunnelAsync for subsequent port list/create/delete operations and added an auto-selected-region startup regression test.

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

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread src/Aspire.Hosting.DevTunnels/DevTunnelResourceBuilderExtensions.cs
Copilot AI review requested due to automatic review settings September 1, 2026 09:05

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

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@mitchdenny

Copy link
Copy Markdown
Member

PR Testing Report

PR Information

Artifact Version Verification

  • Artifact: cli-native-archives-osx-arm64
  • Installed Aspire CLI: 13.6.0-pr.19230.g278449bd
  • Expected Commit: 278449bd72703fb7e750b4345890985f312b32a4
  • Status: PASS

The installed PR artifact's embedded commit matches the PR head.

Test Environment

  • macOS arm64
  • Aspire CLI from the PR workflow artifact
  • DevTunnel CLI 1.0.2030+fc9273aa0f
  • File-based AppHosts with a dynamic-port Python HTTP backend
  • Browser-authenticated DevTunnel session

Test Scenarios

Scenario 1: Focused DevTunnel regression tests

Status: PASS

Ran the four startup and health-check tests that exercise explicit and auto-selected regions:

  • OnBeforeResourceStarted_WithRegion_UsesResolvedTunnelIdForPortOperations
  • OnBeforeResourceStarted_WithAutoSelectedRegion_UsesCreatedTunnelIdForPortOperations
  • DevTunnelHealthCheck_WithAutoSelectedRegion_UsesReturnedTunnelIdForAccessOperations
  • DevTunnelHealthCheck_WithRegion_UsesResolvedTunnelIdForTunnelAndAccessOperations

Result: 4 passed, 0 failed.

Scenario 2: Fresh auto-selected-region AppHost

Status: PASS

Started a fresh anonymous DevTunnel without specifying a region.

  • Requested bare ID: tunnel-2f17adde
  • Service-returned qualified ID: tunnel-2f17adde.aue01
  • Initial backend/DevTunnel port: 60917
  • Backend resource: healthy
  • Tunnel resource: healthy
  • Tunnel port: healthy
  • Public endpoint: HTTP 200
  • Public response body: identical to the local backend response

This exercised the changed production path end to end: Aspire created the tunnel with a bare ID, captured the qualified ID returned by the DevTunnel service, created the port, and completed the tunnel health check.

Scenario 3: Existing-tunnel restart

Status: PASS

Stopped and restarted the same AppHost so Aspire encountered the existing tunnel and exercised its update/recreation path.

  • Qualified ID remained tunnel-2f17adde.aue01
  • Dynamic backend/DevTunnel port changed from 60917 to 61155
  • Stale port handling and new port creation completed
  • Backend, tunnel, and new tunnel port converged to healthy

Scenario 4: Bare versus qualified per-port access lookup

Status: PASS, with changed upstream behavior

Compared direct per-port access-list calls against the same live tunnel:

  • Bare ID exit code: 0
  • Qualified ID exit code: 0

DevTunnel CLI 1.0.2030 now accepts both forms, so the historical bare-ID failure from issue #18790 could not be reproduced against the current service/CLI. The PR's qualified-ID path was still verified by the focused fake-client tests and by the healthy live auto-region tunnel.

Scenario 5: Explicit AustraliaEast region control

Status: BLOCKED by regional service authentication

The explicit-region tunnel failed during tunnel creation, before the PR's changed qualified-ID, port, or health-check logic could execute. The regional endpoint returned:

Unauthorized tunnel creation access: Anonymous does not have 'create' access scope

Aspire invoked the expected regional service URI:

https://aue.rel.tunnels.api.visualstudio.com

A direct manual DevTunnel CLI create against that URI failed identically despite the CLI being logged in against the global service. This is an environment/service authentication limitation rather than evidence of a regression in this PR.

Summary

Scenario Status Notes
PR artifact/version verification PASS Installed artifact matches PR head
Focused regression tests PASS 4/4 passed
Fresh auto-region E2E PASS Qualified ID captured; tunnel and port healthy
Existing-tunnel restart PASS Update/recreation path healthy on new port
Bare/qualified access comparison PASS Both accepted by current DevTunnel CLI
Explicit-region control BLOCKED Regional endpoint treated logged-in client as anonymous before changed logic ran

Overall Result

PR VERIFIED for the changed auto-selected-region behavior.

The exact production scenario targeted by the PR passed with the PR artifact, including a restart. No PR regression was found. The explicit-region control remains inconclusive because the regional DevTunnel service rejected tunnel creation before the relevant code path.

Cleanup

  • Explicit-region AppHost stopped successfully.
  • Auto-region AppHost stopped successfully.
  • Test tunnel tunnel-2f17adde.aue01 deleted successfully.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-integrations Issues pertaining to Aspire Integrations packages

5 participants