VSCode

Microsoft authentication provider is not available (VSCode settings sync) – AADSTS700003

I have been using settings sync in Visual Studio Code since it was first released in the Insiders build and it has been working well for me, I currently sync settings from Insiders and Stable releases on four different Windows machines and one MacBook Pro. Then, all of a sudden the Insiders instance on one of the Windows computers stopped syncing;

Microsoft is currently not available

Weirdly enough, the Stable build on the same machine kept happily working and syncing settings, suggesting the problem was specific to this Insiders installation and not some machine wide problem. It’s worth pointing out again installation, it was not even a problem with the general Insiders build since the same build was still working fine on all other machines.

At first I tried to start VSCode without extensions (code-insiders --disable-extensions), then I tried to fully remove VSCode (and manually deleted all relevant folders under my local profile), restarted Windows… the usual deal, all with no luck. I then decided to open an issue on GitHub (more on that later) while I continued my investigation; the first comment from RMacfarlane suggested something might have changed with the network configuration on the machine, but again, that should have affected the Stable release as well. I checked anyway and made sure code-insiders was allowed through Windows Firewall (it was). So I decided to take a look at the failing code; Settings Sync (or rather, miccrosoft-authentication in this case) is a built-in extension that can be found under C:\Users\<user>\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\extensions\microsoft-authentication\dist\extension.js or /Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/extensions/microsoft-authentication/dist/extension.js on macOS. The file needs to be beautified but once done it was easy to find the failing method:

private async refreshToken(refreshToken: string, scope: string, sessionId: string): Promise < IToken > {
    try {
        Logger.info('Refreshing token...');
        const postData = querystring.stringify({
            refresh_token: refreshToken,
            client_id: clientId,
            grant_type: 'refresh_token',
            scope: scope
        });

        const result = await fetch(`https://login.microsoftonline.com/${tenant}/oauth2/v2.0/token`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Content-Length': postData.length.toString()
            },
            body: postData
        });
        if(result.ok) {
            const json = await result.json();
            const token = this.getTokenFromResponse(json, scope, sessionId);
            this.setToken(token, scope);
            Logger.info('Token refresh success');
            return token;
        } else {
            Logger.error(`Refreshing token failed: ${result.statusText}`);
            throw new Error('Refreshing token failed.');
        }
    } catch (e) {
        Logger.error('Refreshing token failed');
        throw new Error(REFRESH_NETWORK_FAILURE);
    }
}

Clearly it is a network communication failure of some kind, so the next logical step was to analyze the network traffic: Fiddler in this case was enough:

INSIDERS
    REQUEST
        POST https://login.microsoftonline.com/organizations/oauth2/v2.0/token HTTP/1.1
        Content-Type: application/x-www-form-urlencoded
        Content-Length: 1688
        Accept: */*
        User-Agent: node-fetch/1.0 (+https://github.com/bitinn/node-fetch)
        Accept-Encoding: gzip,deflate
        Connection: close
        Host: login.microsoftonline.com
        refresh_token=0.AAAAMe_N-B6jS[...]

    RESPONSE
        HTTP/1.1 400 Bad Request
        Cache-Control: no-store, no-cache
        Pragma: no-cache
        Content-Length: 566
        Content-Type: application/json; charset=utf-8
        Expires: -1
        Strict-Transport-Security: max-age=31536000; includeSubDomains
        X-Content-Type-Options: nosniff
        P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
        x-ms-request-id: 6a98c866-d152-4b8c-9323-c267643a4d00
        x-ms-ests-server: 2.1.11063.7 - WUS2 ProdSlices
        report-to: {"group":"network-errors","max_age":86400,"endpoints":[{"url":"https://ffde.nelreports.net/api/report?cat=estscorp+wst"}]}
        nel: {"report_to":"network-errors","max_age":86400,"success_fraction":0.001,"failure_fraction":1.0}
        Set-Cookie: fpc=AhzP-6kQ6rNOhtjP3prNTV6b5UYsAQAAACC19NYOAAAA; expires=Sat, 17-Oct-2020 01:38:41 GMT; path=/; secure; HttpOnly; SameSite=None
        Set-Cookie: x-ms-gateway-slice=corp; path=/; secure; samesite=none; httponly
        Set-Cookie: stsservicecookie=estscorp; path=/; secure; samesite=none; httponly
        Date: Thu, 17 Sep 2020 01:38:40 GMT
        Connection: close
        {"error":"invalid_grant","error_description":"AADSTS700003: Device object was not found in the tenant 'f8cdef31-a31e-4b4a-93e4-5f571e91255a' directory.\r\nTrace ID: 6a98c866-d152-4b8c-9323-c267643a4d00\r\nCorrelation ID: 7783e740-4e79-4c3c-82c5-32224fdfd7bf\r\nTimestamp: 2020-09-17 01:38:41Z","error_codes":[700003],"timestamp":"2020-09-17 01:38:41Z","trace_id":"6a98c866-d152-4b8c-9323-c267643a4d00","correlation_id":"7783e740-4e79-4c3c-82c5-32224fdfd7bf","error_uri":"https://login.microsoftonline.com/error?code=700003","suberror":"device_authentication_failed"}

STABLE
    REQUEST
        POST https://login.microsoftonline.com/organizations/oauth2/v2.0/token HTTP/1.1
        Content-Type: application/x-www-form-urlencoded
        Content-Length: 1760
        Accept: */*
        User-Agent: node-fetch/1.0 (+https://github.com/bitinn/node-fetch)
        Accept-Encoding: gzip,deflate
        Connection: close
        Host: login.microsoftonline.com
        refresh_token=0.AAAAMe_N-B6jSkuT5 [...]

    RESPONSE
        HTTP/1.1 200 OK
        Cache-Control: no-store, no-cache
        Pragma: no-cache
        Content-Length: 4659
        Content-Type: application/json; charset=utf-8
        Expires: -1
        Strict-Transport-Security: max-age=31536000; includeSubDomains
        X-Content-Type-Options: nosniff
        P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
        client-request-id: 587d8a8b-a4e3-4ad1-b038-fb82fca5cbb3
        x-ms-request-id: 6ee921d4-44eb-4bbd-a7d2-b92a2a333500
        x-ms-ests-server: 2.1.11063.7 - EUS ProdSlices
        x-ms-clitelem: 1,0,0,3052114141.4735,
        Set-Cookie: fpc=Atn7i5LhCDlCqLjF_Sco5A_X5sDqAQAAAAa29NYOAAAA; expires=Sat, 17-Oct-2020 01:42:31 GMT; path=/; secure; HttpOnly; SameSite=None
        Set-Cookie: x-ms-gateway-slice=estsfd; path=/; secure; httponly
        Set-Cookie: stsservicecookie=estsfd; path=/; secure; httponly
        Date: Thu, 17 Sep 2020 01:42:31 GMT
        Connection: close
        [...]

So the authentication attempt was failing with a code 400 (Bad Request) and the error description is AADSTS700003: Device object was not found in the tenant 'f8cdef31-a31e-4b4a-93e4-5f571e91255a' directory . Google and StackOverflow were not very helpful in this case, I only found some general information out of the error code.

Decided to not give up I tried to logout of all authentication providers in VSCode Insiders (currently Microsoft and GitHub are supported), that didn’t solve the problem but made me notice that when I tried to enable Settings Sync back, I was not prompted to authenticate as I would have expected; that means credentials where cached somewhere, and I already knew it was not in a temporary folder used by vscode because I had already cleared them all… On Windows, a place to check for cached credentials is Windows Credential Manager: I noticed two entries related to VSCode Insiders, one for each authentication provider:

Windows Credential Manager

I deleted those two entries, re-enabled Settings Sync and sure enough I was able to authenticate and sync my settings again đź‘Ť.

Heres the GitHub issue I opened: https://github.com/microsoft/vscode/issues/106321; RMacfarlane has synce pushed an update to prevent this to happen again, you can see the details in this pull request.


You cannot shake hands with aclenched fist. Golda Meir

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.