Issues with device authentication

Hi,

We’re using Pritunl with Azure AD SSO and Device authentication on OCI.

We have 2 servers behind an OCI Load Balancer.

We are able to connect only 50% of the time, we get “invalid device token” on the server, client says “Failed to authenticate”

This happens on both servers, but both are able to connect correctly 50% of the time

[nickel-4000] 2025-10-21 09:35:04 us=269482 1 variation(s) on previous 8 message(s) suppressed by --mute
[nickel-4000] 2025-10-21 09:35:04 us=269532 read UDPv4 [ECONNREFUSED]: Connection refused (fd=5,code=111)
[nickel-4000] 2025-10-21 09:35:08 us=337064 Connection Attempt MULTI: multi_create_instance called
[nickel-4000] 2025-10-21 09:35:08 us=337146 45.147.210.231:62378 Re-using SSL/TLS context
[nickel-4000] 2025-10-21 09:35:08 us=337254 45.147.210.231:62378 Outgoing Control Channel Authentication: Using 160 bit message hash ‘SHA1’ for HMAC authentication
[nickel-4000] 2025-10-21 09:35:08 us=337286 45.147.210.231:62378 Incoming Control Channel Authentication: Using 160 bit message hash ‘SHA1’ for HMAC authentication
[nickel-4000] 2025-10-21 09:35:08 ERROR User auth failed “Invalid device token”
[nickel-4000] 2025-10-21 09:35:08 COM> SUCCESS: client-deny command succeeded

Any way to debug this ?

Thanks

Here’s a log a couple minutes apart

success

[nickel-4000] 2025-10-21 19:20:40 us=28696 Connection Attempt MULTI: multi_create_instance called
[nickel-4000] 2025-10-21 19:20:40 us=28764 XX.YY.ZZ.TT:51807 Re-using SSL/TLS context
[nickel-4000] 2025-10-21 19:20:40 us=28849 XX.YY.ZZ.TT:51807 Outgoing Control Channel Authentication: Using 160 bit message hash ‘SHA1’ for HMAC authentication
[nickel-4000] 2025-10-21 19:20:40 us=28880 XX.YY.ZZ.TT:51807 Incoming Control Channel Authentication: Using 160 bit message hash ‘SHA1’ for HMAC authentication
[nickel-4000] 2025-10-21 19:20:40 us=28979 XX.YY.ZZ.TT:51807 Control Channel MTU parms [ mss_fix:0 max_frag:0 tun_mtu:1250 tun_max_mtu:0 headroom:126 payload:1600 tailroom:126 ET:0 ]
[nickel-4000] 2025-10-21 19:20:40 us=29021 XX.YY.ZZ.TT:51807 Data Channel MTU parms [ mss_fix:0 max_frag:0 tun_mtu:1500 tun_max_mtu:1600 headroom:136 payload:1768 tailroom:562 ET:0 ]
[nickel-4000] 2025-10-21 19:20:40 us=44827 XX.YY.ZZ.TT:51807 VERIFY OK: depth=1, O=68de9ed3216dfec506a72924, CN=68de9ed3216dfec506a72925
[nickel-4000] 2025-10-21 19:20:40 us=45020 XX.YY.ZZ.TT:51807 VERIFY OK: depth=0, O=68de9ed3216dfec506a72924, CN=68de9ed4216dfec506a72937
[nickel-4000] 2025-10-21 19:20:40 us=45412 XX.YY.ZZ.TT:51807 peer info: IV_VER=2.6.12
[nickel-4000] 2025-10-21 19:20:40 us=45447 XX.YY.ZZ.TT:51807 peer info: IV_PLAT=win
[nickel-4000] 2025-10-21 19:20:40 us=45476 XX.YY.ZZ.TT:51807 peer info: IV_TCPNL=1
[nickel-4000] 2025-10-21 19:20:40 us=45573 XX.YY.ZZ.TT:51807 peer info: IV_MTU=1600
[nickel-4000] 2025-10-21 19:20:40 us=45615 XX.YY.ZZ.TT:51807 peer info: IV_NCP=2
[nickel-4000] 2025-10-21 19:20:40 us=45641 XX.YY.ZZ.TT:51807 peer info: IV_CIPHERS=AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305:AES-256-CBC:AES-128-CBC
[nickel-4000] 2025-10-21 19:20:40 us=45665 XX.YY.ZZ.TT:51807 peer info: IV_PROTO=990
[nickel-4000] 2025-10-21 19:20:40 us=45690 XX.YY.ZZ.TT:51807 peer info: IV_LZO_STUB=1
[nickel-4000] 2025-10-21 19:20:40 us=45715 XX.YY.ZZ.TT:51807 peer info: IV_COMP_STUB=1
[nickel-4000] 2025-10-21 19:20:40 us=45740 XX.YY.ZZ.TT:51807 peer info: IV_COMP_STUBv2=1
[nickel-4000] 2025-10-21 19:20:40 us=45768 XX.YY.ZZ.TT:51807 peer info: IV_HWADDR=a8:b1:3b:98:0e:50
[nickel-4000] 2025-10-21 19:20:40 us=45795 XX.YY.ZZ.TT:51807 peer info: IV_SSL=OpenSSL_3.3.1_4_Jun_2024
[nickel-4000] 2025-10-21 19:20:40 us=45817 XX.YY.ZZ.TT:51807 peer info: IV_PLAT_VER=10.0,_amd64_executable
[nickel-4000] 2025-10-21 19:20:40 us=45870 XX.YY.ZZ.TT:51807 peer info: UV_ID=8dafcc5ef3d1417881246b2e3e7aaba7
[nickel-4000] 2025-10-21 19:20:40 us=45901 XX.YY.ZZ.TT:51807 peer info: UV_NAME=helium-7837
[nickel-4000] 2025-10-21 19:20:40 us=45929 XX.YY.ZZ.TT:51807 peer info: UV_PRITUNL_VER=1.3.4392.66
[nickel-4000] 2025-10-21 19:20:40 us=46138 XX.YY.ZZ.TT:51807 TLS: Username/Password authentication deferred for username ‘Oa2WDoZ1xfZRcaltULhaeFvIVDa/zHwI8P373iddoCI’
[nickel-4000] 2025-10-21 19:20:40 us=46187 XX.YY.ZZ.TT:51807 TLS: move_session: dest=TM_ACTIVE src=TM_INITIAL reinit_src=1
[nickel-4000] 2025-10-21 19:20:40 us=46395 XX.YY.ZZ.TT:51807 NOTE: --mute triggered…
[nickel-4000] 2025-10-21 19:20:40 us=50159 XX.YY.ZZ.TT:51807 2 variation(s) on previous 8 message(s) suppressed by --mute
[nickel-4000] 2025-10-21 19:20:40 us=50193 XX.YY.ZZ.TT:51807 [68de9ed4216dfec506a72937] Peer Connection Initiated with [AF_INET]XX.YY.ZZ.TT:51807
[nickel-4000] 2025-10-21 19:20:41 us=187076 XX.YY.ZZ.TT:51807 PUSH: Received control message: ‘PUSH_REQUEST’
[nickel-4000] 2025-10-21 19:20:43 client-kill “remove_multi”
[nickel-4000] 2025-10-21 19:20:43 User disconnected user_id=68de9ed4216dfec506a72937
[nickel-4000] 2025-10-21 19:20:43 COM> SUCCESS: client-kill command succeeded
[nickel-4000] 2025-10-21 19:20:43 us=316654 MANAGEMENT: CMD ‘client-kill 2’
[nickel-4000] 2025-10-21 19:20:43 Client conf 68de9ed4216dfec506a72937:
[nickel-4000] 2025-10-21 19:20:43 us=316712 Delayed exit in 5 seconds
[nickel-4000] 2025-10-21 19:20:43 push “ping 10”
[nickel-4000] 2025-10-21 19:20:43 us=316767 SENT CONTROL [68de9ed4216dfec506a72937]: ‘RESTART’ (status=1)
[nickel-4000] 2025-10-21 19:20:43 push “ping-exit 60”
[nickel-4000] 2025-10-21 19:20:43 push “dhcp-option DNS 192.168.3.40”
[nickel-4000] 2025-10-21 19:20:43 ifconfig-push 172.17.100.3 255.255.255.0
[nickel-4000] 2025-10-21 19:20:43 us=373498 MANAGEMENT: CMD ‘client-auth 4 1’
[nickel-4000] 2025-10-21 19:20:43 COM> SUCCESS: client-auth command succeeded
[nickel-4000] 2025-10-21 19:20:46 us=454997 XX.YY.ZZ.TT:51807 PUSH: Received control message: ‘PUSH_REQUEST’
[nickel-4000] 2025-10-21 19:20:46 User connected user_id=68de9ed4216dfec506a72937
[nickel-4000] 2025-10-21 19:20:46 us=455262 MULTI: new connection by client ‘68de9ed4216dfec506a72937’ will cause previous active sessions by this client to be dropped. Remember to use the --duplicate-cn option if you want multiple clients using the same certificate or username to concurrently connect.
[nickel-4000] 2025-10-21 19:20:46 us=455299 MULTI_sva: pool returned IPv4=172.17.100.2, IPv6=(Not enabled)
[nickel-4000] 2025-10-21 19:20:46 us=455396 MULTI: Learn: 172.17.100.3 → 68de9ed4216dfec506a72937/XX.YY.ZZ.TT:51807
[nickel-4000] 2025-10-21 19:20:46 us=455424 MULTI: primary virtual IP for 68de9ed4216dfec506a72937/XX.YY.ZZ.TT:51807: 172.17.100.3
[nickel-4000] 2025-10-21 19:20:46 us=455463 Data Channel MTU parms [ mss_fix:1399 max_frag:0 tun_mtu:1500 tun_max_mtu:1600 headroom:136 payload:1768 tailroom:562 ET:0 ]
[nickel-4000] 2025-10-21 19:20:46 us=455526 Outgoing dynamic tls-crypt: Cipher ‘AES-256-CTR’ initialized with 256 bit key
[nickel-4000] 2025-10-21 19:20:46 us=455560 Outgoing dynamic tls-crypt: Using 256 bit message hash ‘SHA256’ for HMAC authentication
[nickel-4000] 2025-10-21 19:20:46 us=455585 NOTE: --mute triggered…
[nickel-4000] 2025-10-21 19:20:46 us=455663 4 variation(s) on previous 8 message(s) suppressed by --mute
[nickel-4000] 2025-10-21 19:20:46 us=455691 SENT CONTROL [68de9ed4216dfec506a72937]: ‘PUSH_REPLY,comp-lzo no,route 192.168.3.0 255.255.255.0,route 100.97.162.0 255.255.255.0,route-gateway 172.17.100.1,topology subnet,ping 10,ping-exit 60,dhcp-option DNS 192.168.3.40,ifconfig 172.17.100.3 255.255.255.0,peer-id 1,cipher AES-128-GCM,protocol-flags cc-exit tls-ekm dyn-tls-crypt,tun-mtu 1500’ (status=1)
[nickel-4000] 2025-10-21 19:20:47 us=29070 68de9ed4216dfec506a72937/XX.YY.ZZ.TT:51807 Data Channel: cipher ‘AES-128-GCM’, peer-id: 0, compression: ‘stub’
[nickel-4000] 2025-10-21 19:20:47 us=29121 68de9ed4216dfec506a72937/XX.YY.ZZ.TT:51807 Timers: ping 10, ping-restart 80
[nickel-4000] 2025-10-21 19:20:47 us=29145 68de9ed4216dfec506a72937/XX.YY.ZZ.TT:51807 NOTE: --mute triggered…

failure

[nickel-4000] 2025-10-21 19:24:03 us=926482 Connection Attempt MULTI: multi_create_instance called
[nickel-4000] 2025-10-21 19:24:03 us=926563 XX.YY.ZZ.TT:57508 Re-using SSL/TLS context
[nickel-4000] 2025-10-21 19:24:03 us=926648 XX.YY.ZZ.TT:57508 Outgoing Control Channel Authentication: Using 160 bit message hash ‘SHA1’ for HMAC authentication
[nickel-4000] 2025-10-21 19:24:03 us=926679 XX.YY.ZZ.TT:57508 Incoming Control Channel Authentication: Using 160 bit message hash ‘SHA1’ for HMAC authentication
[nickel-4000] 2025-10-21 19:24:03 us=926785 XX.YY.ZZ.TT:57508 Control Channel MTU parms [ mss_fix:0 max_frag:0 tun_mtu:1250 tun_max_mtu:0 headroom:126 payload:1600 tailroom:126 ET:0 ]
[nickel-4000] 2025-10-21 19:24:03 COM> SUCCESS: client-deny command succeeded
[nickel-4000] 2025-10-21 19:24:03 ERROR User auth failed “Invalid device token”
[nickel-4000] 2025-10-21 19:24:03 us=926812 XX.YY.ZZ.TT:57508 Data Channel MTU parms [ mss_fix:0 max_frag:0 tun_mtu:1500 tun_max_mtu:1600 headroom:136 payload:1768 tailroom:562 ET:0 ]
[nickel-4000] 2025-10-21 19:24:03 us=941567 XX.YY.ZZ.TT:57508 VERIFY OK: depth=1, O=68de9ed3216dfec506a72924, CN=68de9ed3216dfec506a72925
[nickel-4000] 2025-10-21 19:24:03 us=941714 XX.YY.ZZ.TT:57508 VERIFY OK: depth=0, O=68de9ed3216dfec506a72924, CN=68de9ed4216dfec506a72937
[nickel-4000] 2025-10-21 19:24:03 us=941968 XX.YY.ZZ.TT:57508 peer info: IV_VER=2.6.12
[nickel-4000] 2025-10-21 19:24:03 us=941993 XX.YY.ZZ.TT:57508 peer info: IV_PLAT=win
[nickel-4000] 2025-10-21 19:24:03 us=942020 XX.YY.ZZ.TT:57508 peer info: IV_TCPNL=1
[nickel-4000] 2025-10-21 19:24:03 us=942034 XX.YY.ZZ.TT:57508 peer info: IV_MTU=1600
[nickel-4000] 2025-10-21 19:24:03 us=942067 XX.YY.ZZ.TT:57508 peer info: IV_NCP=2
[nickel-4000] 2025-10-21 19:24:03 us=942099 XX.YY.ZZ.TT:57508 peer info: IV_CIPHERS=AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305:AES-256-CBC:AES-128-CBC
[nickel-4000] 2025-10-21 19:24:03 us=942122 XX.YY.ZZ.TT:57508 peer info: IV_PROTO=990
[nickel-4000] 2025-10-21 19:24:03 us=942137 XX.YY.ZZ.TT:57508 peer info: IV_LZO_STUB=1
[nickel-4000] 2025-10-21 19:24:03 us=942150 XX.YY.ZZ.TT:57508 peer info: IV_COMP_STUB=1
[nickel-4000] 2025-10-21 19:24:03 us=942164 XX.YY.ZZ.TT:57508 peer info: IV_COMP_STUBv2=1
[nickel-4000] 2025-10-21 19:24:03 us=942178 XX.YY.ZZ.TT:57508 peer info: IV_HWADDR=a8:b1:3b:98:0e:50
[nickel-4000] 2025-10-21 19:24:03 us=942191 XX.YY.ZZ.TT:57508 peer info: IV_SSL=OpenSSL_3.3.1_4_Jun_2024
[nickel-4000] 2025-10-21 19:24:03 us=942240 XX.YY.ZZ.TT:57508 peer info: IV_PLAT_VER=10.0,_amd64_executable
[nickel-4000] 2025-10-21 19:24:03 us=942260 XX.YY.ZZ.TT:57508 peer info: UV_ID=8dafcc5ef3d1417881246b2e3e7aaba7
[nickel-4000] 2025-10-21 19:24:03 us=942274 XX.YY.ZZ.TT:57508 peer info: UV_NAME=helium-7837
[nickel-4000] 2025-10-21 19:24:03 us=942287 XX.YY.ZZ.TT:57508 peer info: UV_PRITUNL_VER=1.3.4392.66
[nickel-4000] 2025-10-21 19:24:03 us=942344 XX.YY.ZZ.TT:57508 TLS: Username/Password authentication deferred for username ‘oApP6/p6XM1dYq3LPijfNPWTJL2N4DvS+XQgyILvXww’
[nickel-4000] 2025-10-21 19:24:03 us=942367 XX.YY.ZZ.TT:57508 TLS: move_session: dest=TM_ACTIVE src=TM_INITIAL reinit_src=1
[nickel-4000] 2025-10-21 19:24:03 us=942410 XX.YY.ZZ.TT:57508 NOTE: --mute triggered…
[nickel-4000] 2025-10-21 19:24:03 us=945944 XX.YY.ZZ.TT:57508 2 variation(s) on previous 8 message(s) suppressed by --mute
[nickel-4000] 2025-10-21 19:24:03 us=945971 XX.YY.ZZ.TT:57508 [68de9ed4216dfec506a72937] Peer Connection Initiated with [AF_INET]XX.YY.ZZ.TT:57508
[nickel-4000] 2025-10-21 19:24:03 us=997482 MANAGEMENT: CMD ‘client-deny 6 1 “Invalid device token”’
[nickel-4000] 2025-10-21 19:24:03 us=997528 MULTI: connection rejected: Invalid device token, CLI:[NULL]
[nickel-4000] 2025-10-21 19:24:04 us=990509 XX.YY.ZZ.TT:57508 Delayed exit in 5 seconds
[nickel-4000] 2025-10-21 19:24:04 us=990569 XX.YY.ZZ.TT:57508 SENT CONTROL [UNDEF]: ‘AUTH_FAILED’ (status=1)
[nickel-4000] 2025-10-21 19:24:04 us=990613 XX.YY.ZZ.TT:57508 SENT CONTROL [68de9ed4216dfec506a72937]: ‘AUTH_FAILED’ (status=1)
[nickel-4000] 2025-10-21 19:24:04 us=990642 XX.YY.ZZ.TT:57508 NOTE: --mute triggered…
[nickel-4000] 2025-10-21 19:24:06 us=100321 1 variation(s) on previous 8 message(s) suppressed by --mute
[nickel-4000] 2025-10-21 19:24:06 us=100372 read UDPv4 [ECONNREFUSED]: Connection refused (fd=5,code=111)
[nickel-4000] 2025-10-21 19:24:09 us=559066 XX.YY.ZZ.TT:57508 SIGTERM[soft,delayed-exit] received, client-instance exiting

There seems to be a problem when a load balancer is used

I enabled sticky session on the load balancer, so now the same pritunl server receives all requests from the client when connecting to the global sync address.

Suppose server now getting all the requests from the LB address is A , the other one is B

Now if the client tries to establish connection to A it works, however if it randomly choses B it will not.

I analyzed the traffic with tcpdump -A -i lo ‘tcp port 9756’ to check what arrives on which server, and in the situation where the client chooses B (as we see in the client), it actually receives no traffic. All the traffic is actually sent to A

So I believe at one point the traffic from the client is sent to the LB adress instead of the chosen server address.

Device authentication requires the public address in the hosts tab to either be the IP address or DNS entry for that specific host, it can’t be a load balancer. The device authentication is scoped only to one host. Below are all the addresses and how to configure them.

Hosts Tab

  • Host Public Address: The public IPv4 address or domain of the Pritunl host. This should always be the public IP of the host for all configurations even when using a load balancer.
  • Host Public IPv6 Address: The public IPv6 address or domain of the Pritunl host. This should always be the public IP of the host for all configurations even when using a load balancer.
  • Host Sync Address: In the advanced host settings. The public address or domain that the web server of the Pritunl servers can be accessed from. If a load balancer is configured that address should be set here.

Top Right Settings

  • Connection Single Sign-On Domain: Only shown when using single sign-on connection authentication. The public address or domain that is used to validate single sign-on requests through the Pritunl web server for a new VPN connection. If a load balancer is configured that address should be set here. Requires valid SSL certificate.

Hi,

Yes this is the configuration we have

However there is an issue in the traffic because of this scoping

I have Load Balancer LB, Server A, Server B

I set the LB to send all traffic to server A.

What happens is that all HTTP traffic from the client, including the device token, is sent to the load balancer and then server A (POST /key/ovpn/xxxxxx with JSON Data containing device_signature field )

As a consequence, if the client choses randomly the IP of Server A it works, but if it choses Server B it will fail because it didn’t receive the query and the deviceid

What would be expected is that the data POST is sent to the server A or server B address, not the LB address.

I did some network sniffing on the client, and server A and server B receive no TCP traffic , only UDP so it means they don’t receive the device token info directly, it’s actually sent to the LB which causes the problem.

In the host settings I have

Public Adress : server A’s DNS name

Sync Address : LB’s name

PS : I disabled SSO for testing purposes

The POST /key/ovpn completes the device authentication and returns a token that is scoped only to the server that handled the request. It will also return the public address of that server and the client will then connect to that VPN server using the token. For this reason the public address field in the host settings must point to the actual host not a load balancer.

This is the case, the public address field points to the real public address of the server.

However, it seems the POST /key/ovpn queries are sent to the Load Balancer,.

I analyzed the TLS trafic on the client and here’s the flow

  1. https://LB/key/sync
  2. https://LB/key/ovpn with device token in JSON
  3. NSlookup query on DNS names of serverA or server B

It appears the client choses the server it will use AFTER the POST /key/ovpn which is sent on the LB.

As a result, in the case where the server answering from the LB is not the one the client choses afterwards, the connection will fail.

I believe the flow should be

  1. https://LB/key/sync
  2. Choose server A or Server B
  3. https://ServerA/key/ovpn or https://ServerB/key/ovpn

Thanks

The /key/sync is a configuration update to sync any changes, it isn’t part of the VPN authentication or server selection. The /key/ovpn request will return token, remote and remote6 using the public address and public IPv6 address fields from the host settings. This is the address that will be used to connect to the VPN.

This is not what happens. If I force only Server A to answer from the backend pool, we should see only connections to server A.

What actually happens is that after the /key/sync query the client still chooses randomly from the pool it knows, so if it choses server A then the connection works, but if we are out of luck and it choses server B, connection fails

Also the connection: Resolved remotes and connection: Attempting remote have unexpected values

2025-10-24 12:11:14][INFO] :play_button: connection: Resolved remotes ◆ public_address=“” ◆ public_address6=“”
◆ remotes=string{“lb.domain.com*”, “serverb.domain.com”, “servera.domain.com”} ◆ sort_method=“random”

[2025-10-24 12:11:14][INFO] :play_button: connection: Attempting remote ◆ client_disconnect=false ◆ client_disconnect_waiters=0 ◆ client_disconnected=false ◆ client_provider=true
◆ client_startime=0 ◆ data_iface=“” ◆ data_mode=“” ◆ data_remotes=string{“lb.domain.com*”, “serverb.domain.com”, “servera.domain.com”}
◆ data_status=“connecting” ◆ data_timestamp=0 ◆ data_tun_iface=“” ◆ ovpn_auth_failed=false ◆ ovpn_cmd=false ◆ ovpn_connected=false
◆ ovpn_dir=“C:\Program Files (x86)\Pritunl\openvpn” ◆ ovpn_last_auth_failed=-1 ◆ ovpn_management_pass=false
◆ ovpn_management_port=0 ◆ ovpn_path=“C:\Program Files (x86)\Pritunl\openvpn\openvpn.exe” ◆ ovpn_remotes=string{}
◆ ovpn_running=0 ◆ ovpn_tap_iface=“” ◆ profile_device_auth=true ◆ profile_disable_dns=false ◆ profile_disable_gateway=false
◆ profile_dynamic_firewall=false ◆ profile_force_connect=false ◆ profile_force_dns=false ◆ profile_geo_sort=false
◆ profile_id=“649e7c9b9298205a” ◆ profile_mode=“ovpn” ◆ profile_reconnect=true ◆ profile_sso_auth=false
◆ profile_system_profile=false ◆ profile_timeout=false ◆ remote=“lb.domain.com*”
◆ state_closed=false ◆ state_closed_waiters=0 ◆ state_deadline=false ◆ state_delay=false

As you can see “connection: Attempting remote” is trying to connect on the load balancer lb, not Server a nor Server b.

That is the pre-connection authorization not the VPN connection, it should be sent to the load balancer. After that has completed it will return the public address of the server that will be used for the connection.

Hi,

Again, this is not what happens since my load balancer is configured to forward data from only 1 server in the backend. So the expected behaviour would be the client only contacting this server.

What actually happens is that after the preauth, the client still choses randomly a server from the pool of server it gets from the config, and if the server it selects is not the one that replied via the load balancer , the connection will fail (because of the device auth)

As a consequence, in our conf (which is basic 2 servers behind a LB), device authentication doesn’t work

Thanks

Find the connection: Authorization successful log message and check the remote and remote6 values on this log message. Verify these values are correct and that the domains correctly resolve to a specific host not a load balanacer.

Hi,

Yes the remote field after authentication is always serverA as expected.

However in the OpenVPN logs we see 50% connection to serverA and 50% connections to serverB.

Obviously those to serverB will fail :

2025-11-06 09:42:56 UDPv4 link remote: [AF_INET]xx.yy.zz.tt:15106
2025-11-06 09:42:56 WARNING: this configuration may cache passwords in memory – use the auth-nocache option to prevent this
2025-11-06 09:42:56 VERIFY OK: depth=1, O=68de9ed3216dfec506a72924, CN=68de9ed3216dfec506a72925
2025-11-06 09:42:56 NOTE: --mute triggered…
2025-11-06 09:42:56 6 variation(s) on previous 3 message(s) suppressed by --mute
2025-11-06 09:42:56 [68de9ed4216dfec506a7293b] Peer Connection Initiated with [AF_INET]xx.yy.zz.tt:15106
2025-11-06 09:42:58 AUTH: Received control message: AUTH_FAILED
2025-11-06 09:42:58 SIGTERM[soft,auth-failure] received, process exiting