Open the Windows VPN dialog after a failure and it gives you a number and a sentence, of which the sentence is usually the less useful half. The number identifies which stage of the connection failed, and the stage determines which log, which setting and which team you should look at next. Working through the stages in order takes about ten minutes and prevents the familiar sequence of reinstalling adapters, switching protocols and resetting the stack to fix an account that was never permitted to dial in.

Read the number as a stage

A native connection passes through four milestones. It reaches the server and establishes a link, it negotiates security, it authenticates the user, and it applies addressing and routing. A failure at each of those leaves different evidence, and a code that belongs to one stage tells you nothing useful about the others.

The mistake to avoid is treating the code as a severity. A link failure and an authorization failure both read as "could not connect", and they have nothing in common beyond that. Severity tells you how urgent something is; the stage tells you what to open.

Code familyStageWhere the evidence lives
829, 703Link or dial completionClient event log, remote listener reachability
720PPP negotiation and miniport bindingAdapter state, bindings, client log detail
691, 649, 812Identity and authorizationGateway or authentication server decision
Connected, no trafficAddressing, routing and resolutionRoute table and resolver configuration

Stage one: the link and the dial attempt

829 means the underlying link dropped. It does not say whether the remote peer stopped answering, a middlebox killed the session, or a policy on the client closed it. A dial-completion code such as 703 is earlier still: the attempt never got far enough to have a link, which usually points at the profile, the service state or a local policy.

Get-VpnConnection -Name 'Corp' | Select-Object Name,ServerAddress,TunnelType,AuthenticationMethod,ConnectionStatus
Test-NetConnection -ComputerName vpn.example.net -Port 443
Get-WinEvent -LogName Application -MaxEvents 200 | Where-Object ProviderName -match 'RasClient' | Select-Object -First 15 TimeCreated,Id,Message

The event query is the part people skip. A client-side record with a timestamp and an interface name is worth more than the dialog, because it tells you whether the attempt even left the machine. No record plus no listener response is a reachability problem, and no amount of client editing changes it.

If the same profile works on another network, stop here. The code is describing a path condition rather than a configuration error, and the next useful comparison is the two captures rather than another reinstall.

Stage two: PPP and the miniport binding

720 sits between the link and the user. The tunnel came up and then the PPP layer could not negotiate an address or a control protocol, which is often a binding problem on the client rather than a rejected credential. That distinction is the whole value of the code: it says the credential was never reached, so the account is not the suspect.

Get-NetAdapter -IncludeHidden | Where-Object InterfaceDescription -match 'WAN Miniport' | Select-Object Name,Status,ifIndex
Get-NetAdapterBinding | Where-Object ComponentID -match 'ms_pptp|ms_l2tp|ms_sstp|ms_agile' | Select-Object Name,ComponentID,Enabled

Reading those two outputs is more informative than resetting anything. A miniport that is present but not started, or a protocol binding that has been disabled by another piece of software, produces exactly this stage's failure. Both are fixable without touching the rest of the stack. A full reset, by contrast, removes addressing and filter state that had nothing to do with the fault.

Stage three: identity and authorization

691 means the credentials were rejected. 649 means the account is not permitted to dial in, and 812 means a remote access policy declined the connection. These are decisions, not transport faults, and the client can only report them.

The evidence is on the other side. Ask the gateway operator for the attempt at that timestamp and the policy that matched; ask the directory owner whether the account has dial-in permission and whether it is in the group the policy requires. Changing the tunnel type or reinstalling the client cannot alter a decision that was made about an identity.

A useful habit at this stage is to write the exact account string into the ticket, including any domain prefix. A surprising number of 691 cases are a saved credential for the wrong domain, and that is visible in the account string rather than in the protocol settings.

Stage four: connected, and nothing works

A connection can complete and still be useless. It holds an address, the client reports success, and every request the application makes times out. Nothing in the dialog reflects that, and there is no code to look up. At that point the dialog is finished and the useful evidence is somewhere else.

Get-NetRoute -DestinationPrefix 10.24.0.0/16 | Select-Object DestinationPrefix,NextHop,InterfaceAlias
Resolve-DnsName files.corp.example.internal
Test-NetConnection -ComputerName 10.24.6.15 -Port 445

If the route is missing, the server did not push it or the client dropped it. If the route exists and the name fails, resolution is the problem. If both work and the application still fails, you are past the tunnel and into the application's own configuration.

Keep the changes to one layer per test. Every edit you make before the next attempt becomes part of the next code's context, and a code that describes your last edit is worse than no code at all.

One attempt, one change, one record

Whatever the stage, the record should contain the code, the message, the profile name, the timestamp and the network you were on. Five fields, and every one of them is already in front of you in the dialog or the client log. That set is small enough to paste into a ticket and specific enough for someone else to reproduce.

Then put that timestamp next to the record on the other side. The table near the top of this page says which stage owns each disagreement. Without the second record the code only narrows the search; with it, the stage is decided. The comparison is what turns a number into a diagnosis rather than a guess.

That habit covers almost every native Windows VPN fault, and none of the branches requires reinstalling anything. The dialog was always telling you which one you had; the work is in refusing to treat all of them as the same problem.

Sɛbɛn minnu bɛ tali kɛ