Files
daymade e481958195 Release v1.32.0: Add windows-remote-desktop-connection-doctor skill
- Add windows-remote-desktop-connection-doctor v1.0.0 for diagnosing AVD/W365
  connection quality issues with transport protocol analysis and log parsing
- Update claude-md-progressive-disclosurer SKILL.md and references
- Update marketplace to v1.32.0 (37 skills)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 04:45:31 +08:00

7.7 KiB

Windows App Log Analysis Guide

Detailed patterns for parsing Windows App (Microsoft Remote Desktop) diagnostic logs on macOS.

Contents

  • Log file locations
  • Log file naming and rotation
  • Startup health check block
  • Transport negotiation entries
  • Error signatures and their meaning
  • Comparing working vs broken sessions
  • Filtering noise from logs

Log File Locations

macOS

~/Library/Containers/com.microsoft.rdc.macos/Data/Library/Logs/Windows App/

Files follow the pattern:

com.microsoft.rdc.macos_v<version>_<YYYY-MM-DD>_<HH-mm-ss>.log

A new log file is created each day or when the app restarts. Multiple files may exist — sort by modification time to find the most recent:

ls -lt ~/Library/Containers/com.microsoft.rdc.macos/Data/Library/Logs/Windows\ App/

Startup Health Check Block

When the Windows App launches, it runs a health check sequence. A healthy startup produces entries in this order:

Passed: InternetConnectivity
0: 1
4: 3
AvcDecodingCheck: 0
HardwarePresenterCheck: 0
AvcHwDecodingCheck: 1
4: 4
TCP/IP Traffic Routed Through VPN: No
STUN/TURN Traffic Routed Through VPN: Yes

Followed by gateway reachability tests:

Passed URL: https://afdfp-rdgateway-r1.wvd.microsoft.com/ Attempts Made: 1 Used Ipv4: 1 HTTP Status Code: 200 Response Time: 480
Passed URL: https://rdweb.wvd.microsoft.com/ Attempts Made: 1 Used Ipv4: 1 HTTP Status Code: 200 Response Time: 613

What Each Entry Means

Entry Description
Passed: InternetConnectivity General internet reachability confirmed
AvcDecodingCheck / AvcHwDecodingCheck Hardware video decoding capability (0=unavailable, 1=available)
HardwarePresenterCheck Hardware presentation capability
TCP/IP Traffic Routed Through VPN Whether the client detects a VPN intercepting TCP traffic
STUN/TURN Traffic Routed Through VPN Whether the client detects a VPN intercepting STUN/TURN (UDP) traffic
Passed URL: ... Gateway reachability test with response time in ms

When Health Check Fails

If the startup health check block is completely absent from a log, the diagnostic subsystem itself failed. Check for certificate validation errors near the log start:

DIAGNOSTICS(ERR): Failed to validate X509CertificateChain, certificate is not trusted.
BASIX_DCT(ERR): OSSLClosingException thrown, msg=Certificate validation failed

This indicates TLS interception (common with ISP HTTPS proxies in China) or DNS poisoning affecting Microsoft diagnostic endpoints.

Transport Negotiation Entries

FetchClientOptions

This is the critical function that retrieves transport capabilities from the gateway:

GATEWAY(ERR): CWVDTransport::FetchClientOptions exception when attempting to fetch client options: Request timed out
    wvd_transport.cpp(521): FetchClientOptions()

When this times out, the client cannot discover available transport options (including Shortpath). The connection will fall back to WebSocket.

ClientOptions Controller

A separate mechanism that refreshes client properties:

ClientOptions_Controller(ERR): ClientOptionsController RefreshProperties attempt 1 failed: Request timed out. Retrying in 30s...
    client_options.cpp(214): RefreshProperties()

This is less critical than FetchClientOptions but indicates general connectivity issues to Microsoft configuration services.

WebRTC Session

A3CORE(ERR): OnRDWebRTCRedirectorRpc rtcSession not handled

This appears when the server sends a WebRTC session setup but the client does not process it. This may indicate incomplete Shortpath support in the client version, or a session setup that arrives after fallback.

Note: OnRDWebRTCRedirectorRpc notifyClipRectChanged not handled is a benign clipboard-related message, not transport-related.

Error Signatures

Certificate Validation Failure

DIAGNOSTICS(ERR): Failed to validate X509CertificateChain, certificate is not trusted.
A3CORE(ERR): ITrustDelegateAdaptorPtr is empty.
BASIX_DCT(ERR): OSSLClosingException thrown, msg=Certificate validation failed, ossl error string="error:00000000:lib(0)::reason(0)", closing error code=1002

Cause: TLS certificate for Microsoft diagnostic endpoints is not trusted. Common with ISP HTTPS proxies/MITM, DNS poisoning, or corporate proxy servers.

Impact: Prevents the diagnostic health check from completing, which may block transport capability discovery.

Channel Write Failures

"-legacy-"(ERR): Channel::StartWrite failed

Multiple consecutive StartWrite failed errors indicate a connection disruption — the WebSocket or TCP connection to the gateway was interrupted. This is typically followed by a reconnection attempt.

Diagnostics Flush Errors

DIAGNOSTICS(ERR): FlushTracesInternal() is called before BeginUpload(). we don't have a claims token yet

This is a benign telemetry error — the diagnostics system tried to upload traces before authentication completed. Does NOT affect connection quality.

Comparing Working vs Broken Sessions

The most effective diagnostic approach: compare a log from when the connection was healthy (UDP transport) with the current broken log.

Quick Comparison Script

LOG_DIR=~/Library/Containers/com.microsoft.rdc.macos/Data/Library/Logs/Windows\ App

echo "=== Health check and transport entries per log file ==="
for f in "$LOG_DIR"/*.log; do
  echo ""
  echo "--- $(basename "$f") ---"
  grep -c "InternetConnectivity" "$f" 2>/dev/null | xargs -I{} echo "  InternetConnectivity checks: {}"
  grep "Routed Through VPN" "$f" 2>/dev/null | head -2 | sed 's/^/  /'
  grep "Passed URL:" "$f" 2>/dev/null | head -2 | sed 's/^/  /'
  grep "FetchClientOptions" "$f" 2>/dev/null | head -1 | sed 's/^/  /'
  grep "Certificate validation failed" "$f" 2>/dev/null | head -1 | sed 's/^/  /'
done

What to Compare

Aspect Working (UDP) Broken (WebSocket)
Health check block Present, complete Missing or incomplete
TCP/IP Routed Through VPN Present Missing
STUN/TURN Routed Through VPN Present Missing
Passed URL: Present with response times Missing
FetchClientOptions No error Timeout error
Certificate errors None at startup Present at startup

Filtering Noise

Windows App logs contain many repetitive entries that obscure useful information. Filter these out:

grep -v -E "BasicStateManagement|DynVC.*SendChannelClose|dynvcstat.*SerializeToJson|asynctransport\.cpp|FlushTracesInternal"

Common Noise Patterns

Pattern What It Is Safe to Filter
~BasicStateManagement() Transport object destructor Yes
SendChannelClose() Dynamic virtual channel cleanup Yes
SerializeToJson() Channel stats serialization Yes
FlushTracesInternal() Telemetry upload attempt Yes
Stateful object ... destructed while in state Opened Abrupt connection close Context-dependent

The last pattern (Stateful object destructed in Opened state) may be significant during active troubleshooting — it indicates connections being torn down unexpectedly. Keep it when investigating disconnection events.

Activity ID Tracking

Each RDP session gets a unique activity ID (GUID). Track a specific session through the log:

# Find activity IDs from connection events
grep -E "\{[0-9a-f]{8}-" "$LOG_FILE" | grep -v "00000000-0000-0000-0000-000000000000" | head -5

# Trace a specific session
grep "<activity-id>" "$LOG_FILE" | grep -v "BasicStateManagement\|FlushTraces"

The null GUID {00000000-0000-0000-0000-000000000000} indicates background/system events, not specific RDP sessions.