The link authenticates, the client reports connected, and a second later the log closes with LCP terminated by peer. That line comes from PPP negotiation inside the GRE tunnel, so the transport already worked and the two ends disagreed about link options. Passwords and server addresses are usually innocent here. Encryption policy is the first thing to compare, and on Linux the pppd peer file is the first place to look.

What the LCP failure says about the PPP stage

PPTP wraps PPP inside GRE: the TCP 1723 control connection sets up the call, GRE carries the payload, and LCP then negotiates options such as the authentication protocol, compression and MPPE. The peer terminates LCP when a required option is unacceptable on its side. A log where the CHAP or MSCHAPv2 exchange completes and LCP ends immediately afterwards is a policy rejection, not a reachability failure. If the tunnel never reaches negotiation at all, inspect pppd and its plugin before reading the LCP line.

Two preconditions are easy to miss. The pppd binary must exist, and the PPTP plugin named in the peer file must be installed; a missing package ends the dial before any option is discussed.

Enable MPPE on the side that requires it

The real decision is which end owns encryption policy. A client can offer MPPE, require it, or refuse it, and the server makes the same choice. When both require it the link comes up; when one requires and the other refuses, LCP ends.

pty "pptp vpn.example.net --nolaunchpppd"
name alice
remotename PPTP
require-mppe-128

Load the module with modprobe ppp_mppe before dialling, because require-mppe-128 fails without it. On Windows the equivalent control is the security tab of the VPN entry, where the client must be told to require encryption rather than accept whatever the server offers. If the server still terminates LCP, ask its operator whether MPPE is mandatory, optional or disabled, since a client cannot negotiate protection that the server refuses. Turning encryption off to make the message disappear is the wrong direction: it removes the only protection this protocol has.

Save the working peer file before editing it. A mistyped require-mppe line reproduces the same generic LCP failure and sends you back to the beginning.

Read pppd's own log instead of the applet

Desktop applets show the disconnect and hide the reason, so read the daemon's account of one attempt. On systemd systems the message lands in the journal; older setups write to the traditional log files.

journalctl --since "10 min ago" | grep -i -E "pppd|lcp|mppe"
tail -n 50 /var/log/syslog

Grep a window around a single dial rather than a day of reconnects, so the rejected option is easy to spot. pppd usually names the option and the peer's answer, which tells you whether to change your own proposal or ask the server side to relax its requirement. Keep attempts timestamped, because comparing two logs is only useful when you know which lines belong to which call. When no LCP exchange appears at all, the fault sits earlier in the chain and MPPE is not the suspect.

Keep the fix through reconnects: hook names and MTU

Once the link stays up, two details decide whether it survives a reconnect. Hooks live in /etc/ppp/ip-up.d and /etc/network/if-up.d, and both directories are processed by run-parts, whose filename filter rejects anything containing a dot. A script called set-pptp.sh is therefore skipped, while set-pptp executes. Check the name before debugging the script's contents, then set the smaller MTU from inside that hook so each new ppp interface inherits it without a manual command.

run-parts --test /etc/ppp/ip-up.d
ip link set dev ppp0 mtu 1200

To end a session on purpose, target pppd's recorded pid instead of pattern-matching process names, because killing everything that contains ppp also tears down unrelated links. PPTP is deprecated and MS-CHAPv2 is weak, so treat these checks as maintenance for a link that must keep working rather than as a reason to deploy PPTP anywhere new.

Sɛbɛn minnu bɛ tali kɛ