| name | debug-tunnel |
| description | Use when the user reports a tunnel that won't start, won't connect, drops, or shows status 'error'. Pulls the tunnel log buffer and walks through likely causes. Triggers on "tunnel broken", "RDP timed out", "ssh hangs", "why isn't my tunnel working". |
Triage a failing IAP tunnel
Gather evidence (read-only)
tunnels_list — find the failing tunnel (status error, stopped, or stuck in starting).
tunnels_get { tunnelId } — read the embedded logs buffer. Or read the resource iap://tunnels/{tunnelId}/logs for the raw newline-joined buffer.
auth_check — many "tunnel won't start" failures are stale ADC tokens.
Common causes and remedies
| Symptom in logs | Cause | Fix |
|---|
403 ... required permission ... iap.tunnelInstances.accessViaIAP | The current ADC identity lacks IAP TCP forwarding role | Tell the user to grant roles/iap.tunnelResourceAccessor on the VM/project |
dial tcp 127.0.0.1:<port>: bind: address already in use | Another tunnel or app holds the port | tunnels_active to find the conflict; or tunnels_free_port for a fresh one |
connection refused after dial | App not listening on the remote port (e.g., RDP disabled, sshd not running) | Confirm in GCP console that the service is up on the VM |
oauth2: token expired | Stale ADC | auth_login |
instance ... not found | Wrong zone or project | Re-fetch with vms_list { projectId } |
Tunnel sits at starting for >10s | Cold start of IAP, or network ACL drops outgoing 443 to GCP | Stop it (tunnels_stop) and retry; if it still hangs, check the user's egress firewall |
When to escalate
If auth_check succeeds, IAM is correct, port is free, and the tunnel still errors — capture the full logs buffer and ask the user to file an issue. Do not blindly retry more than ~3 times.