ConnMan works for an afternoon and then refuses, and the journal line mentions certificate verification. That line sends people to CA bundles that were never broken. Two different faults produce nearly the same shape of failure: the session cookie expires, or the server certificate actually changed. They are separable in about a minute, and only one of them involves the fingerprint at all.

Two faults, one confusing log line

They separate on two observations, neither of which needs a second read. The first is when the failure started: an expired cookie arrives after hours or days of working, and a replaced certificate arrives right after a gateway change. The second is whether the server's fingerprint still matches, which a fresh authenticate prints for you to compare.

SignalExpired cookieChanged certificate
When it startedafter hours or days of workingright after a gateway change
Fingerprint from a fresh authenticateunchangeddifferent value
Usual log tailHTTP CONNECT 401 / unauthorizedsigner not found / verify failed
Repairreplace the cookie, restartre-pin deliberately, then restart

The one-minute test is the authenticate run below. Compare its FINGERPRINT against OpenConnect.ServerCert in the file. An identical fingerprint with a different COOKIE means replace the cookie only. A different fingerprint means the server certificate really changed, so re-pin it deliberately and record who approved that.

Generate the material instead of typing it

ConnMan has no import step for an OpenConnect profile, unlike NetworkManager. It reads a provisioning file whose values must be produced ahead of time, and the supported way to produce them is OpenConnect's authenticate mode.

sudo openconnect --csd-wrapper=/home/user/.cisco/csd-wrapper.sh \
  --authenticate --user myuser vpn.example.com

The output prints four values: POST, COOKIE, HOST and FINGERPRINT. The fingerprint, prefixed with sha256:, is the server pin. The cookie is the session artifact with a lifetime the gateway decides. Treat them as different kinds of secret: they expire on different schedules, and only one is expected to change.

The file carries both, and they age differently

The provisioning file lives under /var/lib/connman-vpn/ and is read per connection by the VPN daemon rather than by the tray applet. Keep the connection name in the global section and the protocol details in the provider section.

[global]
Name = Company VPN

[provider_openconnect]
Type = OpenConnect
Name = Company Cisco VPN
Host = vpn.example.com
Domain = corp.example
OpenConnect.ServerCert = sha256:...
OpenConnect.Cookie = ...

Use the host name the portal actually serves. A bare IP address can pass the certificate check and still fail, because the appliance routes on the virtual host and expects the name.

systemctl status connman-vpn --no-pager   # is the daemon even installed and running
sudo systemctl restart connman-vpn       # after the file edit
journalctl -u connman-vpn --since '1 hour ago'  # after the connection attempt

What the journal actually shows

The tray tooltip will not say which fault you have. The journal will, if you read the sequence rather than the first alarming line. A stale cookie typically shows the TLS negotiation completing and the HTTP layer rejecting afterwards, which is why the words about certificates sit next to an authorization failure.

Compare a fresh authenticate against the values in the file. If the fingerprint matches and only the cookie differs, you have your answer without touching trust settings.

Refresh the field that expired

Repeat the authenticate command, replace OpenConnect.Cookie, and restart the daemon. Leave the fingerprint alone unless the fresh output shows a different value; in that case the server certificate really was replaced and re-pinning is a decision someone should record rather than a paste from an error message.

Automating the refresh is reasonable: a small script reads the password from standard input, runs authenticate mode, and rewrites only the cookie line. Keep the credential out of the script and readable only by the account that runs it, and make the rewrite atomic so a failed run does not leave a half-written file.

If the refresh is needed every few hours, write the interval down. It is a property of the gateway's session policy, and it decides whether to automate the refresh or ask for a longer session.

Barruulee wal qabatan