This error arrives before the password prompt, which is the useful part: nothing has authenticated yet, so credentials are not the problem. On Linux the same AnyConnect dialog can come from an old protocol version, a 1024-bit key-exchange group, or a cipher suite that the system crypto policy refuses. I have cleared it three different ways on three machines, and what separates those fixes is blast radius rather than cleverness. Each is defensible in the right place and a bad default everywhere else.

Read the message before touching the policy

Keep the exact string out of the dialog. A version complaint points at the protocol layer, a certificate complaint points at trust or naming, and a failed login points at credentials. A gateway offering TLS 1.0 with a 1024-bit DHE group, AES-256-CBC and a SHA-1 signature can hold a perfectly valid certificate and still be rejected by a modern policy before your credentials are ever sent.

Probe the endpoint with the system OpenSSL, using the real hostname and the port the client uses.

openssl s_client -connect vpn.example.com:443 -servername vpn.example.com failing while -tls1 -cipher DEFAULT@SECLEVEL=0 succeeds tells you the boundary is version and key size together. If the first command reports a small DH key rather than a protocol alert, the version is fine and only the group needs attention. Never put a private key or a password into the probe.

Option 1: relax the whole host with the crypto policy

On Fedora and RHEL 8 and 9, update-crypto-policies --set LEGACY lowers OpenSSL's system policy, and update-crypto-policies --show confirms what is active. It usually restores the tunnel, but the policy is read when a process starts, so restart the client and any helper it spawned before you retest. It also permits older protocols and weaker groups for every TLS client on the machine, from the browser in the next window to the package manager that updates the kernel.

That breadth is the whole point and the whole problem. LEGACY is host-wide, persistent and easy to forget, so it should be a diagnostic step or a documented exception on a managed build, never a workstation's resting state. I have seen one that stayed at LEGACY for two years because a single internal portal needed it, and nobody could say when it started.

Debian and Ubuntu have no single switch for this. The equivalent is an edit to /etc/ssl/openssl.cnf that sets a lower MinProtocol and CipherString = DEFAULT@SECLEVEL=0 in the system defaults section. Same blast radius, different file, slightly easier to lose track of during a release upgrade.

Option 2: one config file for one client

A per-process OpenSSL configuration keeps the change inside a single process tree, but only if the file is wired the way the library expects. Naming an ssl_conf section is not enough: OpenSSL reads the top-level openssl_conf key, follows it to an init section, and only then reaches the SSL defaults.

openssl_conf = openssl_init

[openssl_init]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1.0
CipherString = DEFAULT@SECLEVEL=0

Point OPENSSL_CONF at that file and launch the VPN client through a wrapper that exports it. Everything else on the host keeps the default policy, which is the property that matters when the compliance question arrives. Confirm the file is actually in effect before blaming the gateway: OPENSSL_CONF=/path/to/file openssl ciphers -s -tls1 should list TLS 1.0 ciphers, and an empty result means the chain is broken and the client silently kept the system defaults.

The file is version sensitive. OpenSSL 1.1.1 and 3.x accept the same section names, but directive handling around providers changed in 3.x, so verify with the client's own log and a test handshake rather than assuming the file was read at all. A typo in the section name fails open, and the client quietly uses the system defaults.

The limit is coverage. Anything linked against GnuTLS or NSS ignores OPENSSL_CONF, and so does any helper process the client spawns without inheriting the environment. Check which TLS library the binary actually links with ldd before you build the wrapper, because the answer decides whether this option exists at all.

Option 3: a disposable VM or container

For a contractor hitting one legacy gateway for a fortnight, a dedicated VM with the relaxed policy is a cleaner boundary than the workstation. The legacy surface and the everyday browser profile stop sharing a kernel policy, and disposal is a delete rather than an audit finding.

It is still a networked machine, so restrict its access and keep it out of general browsing. The maintenance cost is another image to patch, which is real but bounded and visible, unlike a forgotten LEGACY flag on a laptop.

What the comparison leaves you with

Choose on three questions: who needs the old protocol, for how long, and who will notice if the exception outlives its reason. One app, one person, a few days, points at the per-process config. A whole fleet behind one appliance points at the gateway itself. Anything that needs a permanent LEGACY host policy is a procurement decision wearing a technical costume.

The durable fix belongs on the appliance: TLS 1.2 or later, a group of at least 2048 bits, an AEAD cipher, and a certificate with a modern signature. Ask the appliance owner for that change, then confirm the negotiated version and cipher in the client log. Write the exception down with the host, the gateway, the negotiated protocol, the approver and an expiry date, because the note is what stops a temporary workaround from becoming the default.

Related articles