---
title: 'Tutorial: Manage Failover Settings Using the Access Server CLI'
canonical: https://openvpn.net/as-docs/v3/tutorials/tutorial--manage-failover-from-the-cli/
product: Access Server Docs
description: Configure and manage failover settings in OpenVPN Access Server using the Web API or sacli CLI tools. Learn how to configure, initialize, and test failover nodes for high availability.
---

# Tutorial: Manage Failover Settings Using the Access Server CLI

## Overview

This tutorial shows how to configure and manage failover settings in OpenVPN Access Server using either the Web API or the `sacli` command-line tool.

Access Server supports failover deployments for high availability within a local area network (LAN). In a failover deployment:

- The **primary node** handles active traffic.
- The **secondary node** remains in standby mode.

If the primary node becomes unavailable, the secondary node automatically takes over.

This tutorial explains how to:

1. Validate the failover configuration.
2. Configure failover settings.
3. Initialize the secondary node.
4. Verify failover state changes.
5. Test failover behavior.

To learn more about failover deployments, refer to the [Failover Setup Guide](https://openvpn.net/as-docs/v3/failover-setup.md).

## Prerequisites

- Access Server 3.1.0 or newer (required for Step 1 / Web API method)
- Root access to both Access Server nodes.
- A completed failover deployment setup.

  > **Important**
  >
  > Before following this tutorial, complete Steps 1-6 in [Tutorial: How To Set Up Failover Mode](https://openvpn.net/as-docs/v3/tutorials/tutorial--failover.md).
- (Optional) A remote system for API calls.

## Choose a configuration method

This tutorial provides two ways to configure failover settings:

| **Method** | **Availability** | **Best for** |
| --- | --- | --- |
| Web API (`apicall`) | Access Server 3.1.0 and newer | Automation and API workflows |
| `sacli` commands | All supported Access Server versions | Direct server administration |

Use the method that best fits your environment and workflow.

> **Important**
>
> The failover API specification may change between Access Server releases. Always verify the API documentation for your current version. Refer to: [Tutorial: Test the New Web API (OpenAPI) in Access Server 3.0](https://openvpn.net/as-docs/v3/tutorials/tutorial--test-the-new-web-api--openapi--in-access-server-3-0.md).

## Placeholder values used in this tutorial

Replace the following placeholders with values for your environment:

| **Placeholder** | **Description** |
| --- | --- |
| `<FAILOVER_IP>` | Shared virtual failover IP address |
| `<UCARP_PASSWORD>` | UCARP shared secret password |
| `<PRIMARY_IP>` | IP address of the primary node |
| `<SECONDARY_IP>` | IP address of the secondary node |

> **Tip**
>
> The UCARP secret can be any secure string. Access Server typically generates a random 16-character value containing uppercase letters, lowercase letters, and numbers.

## Step 1: Configure failover using the Web API

> **Note**
>
> This method requires Access Server 3.1.0 or newer.

> **Important**
>
> This tutorial uses `sacli apicall`, but you can also use cURL or Swagger UI. Refer to [Tutorial: Test the New Web API (OpenAPI) in Access Server 3.0](https://openvpn.net/as-docs/v3/tutorials/tutorial--test-the-new-web-api--openapi--in-access-server-3-0.md).

### Configure failover settings

1. Connect to the **primary node** and get root privileges.

   > **Note**
   >
   > All commands in this section run on the primary node.
2. Test the failover configuration:

   ```
   sacli --method POST --url 'api/server/failover-test' --value '{"failover.mode":"ucarp","ucarp.addr":"<FAILOVER_IP>","ucarp.secret":"<UCARP_PASSWORD>","dbpush.hosts.0.enable":true,"dbpush.hosts.0.public":"<PRIMARY_IP>","dbpush.hosts.0.internal":"PRIMARY","dbpush.hosts.0.username":"root","dbpush.hosts.0.password":"","dbpush.hosts.0.ssh_port":22,"dbpush.hosts.1.enable":true,"dbpush.hosts.1.public":"<SECONDARY_IP>","dbpush.hosts.1.internal":"SECONDARY","dbpush.hosts.1.username":"root","dbpush.hosts.1.password":"","dbpush.hosts.1.ssh_port":22}' apicall
   ```

   - Example output:

     ```
     {"ucarp":{"status":true,"message":"UCARP_ADDR_GOOD: ucarp address <FAILOVER_IP> is reachable from locally connected interface on both primary and secondary nodes","friendly":"Shared virtual IP address is directly accessible via locally connected interface on both primary and secondary nodes."},"license_primary":{"status":true,"message":"GOOD_LICENSE: Licensed for 2 concurrent connections.","friendly":"Licensed for 2 concurrent connections."},"license_secondary":{"status":true,"message":"GOOD_LICENSE: Licensed for 2 concurrent connections.","friendly":"Licensed for 2 concurrent connections."},"connectivity":{"status":true,"message":"SUCCEED: failover connectivity test succeeded","friendly":"Connectivity test between primary and secondary nodes succeeded."}}
     ```
3. Save the failover directives/keys into the database:

   ```
   sacli --method POST --url 'api/config-items/Default' --value '{"failover.mode":"ucarp","ucarp.addr":"<FAILOVER_IP>","ucarp.secret":"<UCARP_PASSWORD>","dbpush.hosts.0.enable":true,"dbpush.hosts.0.public":"<PRIMARY_IP>","dbpush.hosts.0.internal":"PRIMARY","dbpush.hosts.0.username":"root","dbpush.hosts.0.password":"","dbpush.hosts.0.ssh_port":22,"dbpush.hosts.1.enable":true,"dbpush.hosts.1.public":"<SECONDARY_IP>","dbpush.hosts.1.internal":"SECONDARY","dbpush.hosts.1.username":"root","dbpush.hosts.1.password":"","dbpush.hosts.1.ssh_port":22}' apicall
   ```

   - Example output:

     ```
     null
     ```
4. Initiate the secondary node (BACKUP):

   ```
   sacli --method POST --url 'api/server/failover-init' --value '{"new_config":{"failover.mode":"ucarp","ucarp.addr":"<FAILOVER_IP>","ucarp.secret":"<UCARP_PASSWORD>","dbpush.hosts.0.enable":"true","dbpush.hosts.0.public":"<PRIMARY_IP>","dbpush.hosts.0.internal":"PRIMARY","dbpush.hosts.0.username":"root","dbpush.hosts.0.password":"","dbpush.hosts.0.ssh_port":"22","dbpush.hosts.1.enable":"true","dbpush.hosts.1.public":"<SECONDARY_IP>","dbpush.hosts.1.internal":"SECONDARY","dbpush.hosts.1.username":"root","dbpush.hosts.1.password":"","dbpush.hosts.1.ssh_port":"22"},"old_config":{"failover.mode":"ucarp","ucarp.addr":"<FAILOVER_IP>","ucarp.secret":"<UCARP_PASSWORD>","dbpush.hosts.0.enable":"true","dbpush.hosts.0.public":"<PRIMARY_IP>","dbpush.hosts.0.internal":"PRIMARY","dbpush.hosts.0.username":"root","dbpush.hosts.0.password":"","dbpush.hosts.0.ssh_port":"22","dbpush.hosts.1.enable":"true","dbpush.hosts.1.public":"<SECONDARY_IP>","dbpush.hosts.1.internal":"SECONDARY","dbpush.hosts.1.username":"root","dbpush.hosts.1.password":"","dbpush.hosts.1.ssh_port":"22"}}' apicall
   ```

   - Example output:

     ```
     {"reason":"Success"}
     ```
5. Restart the primary node (MASTER):

   ```
   sacli --method POST --url 'api/server/restart?restartMode=systemctl' --value '' apicall
   ```

   - Example output:

     ```
     {}
     ```
6. Verify node status:

   ```
   systemctl status openvpnas | grep "Switching to state:" | tail -n1
   ```

   - Example output of MASTER:

     ```
     [WARNING] Switching to state: MASTER
     ```
   - Example output of BACKUP:

     ```
     [WARNING] Switching to state: BACKUP
     ```

## Step 2: Configure failover using sacli

This method works on all supported Access Server versions.

> **Note**
>
> All commands in this section run on the primary node.

### Create the failover configuration file

1. Connect to the primary node and get root privileges.
2. Create the configuration file:

   ```
   nano failover.json
   ```
3. Add the following configuration:

   ```
   {
           "failover.mode": "ucarp",
           "ucarp.addr": "<FAILOVER_IP>",
           "ucarp.secret": "<UCARP_PASSWORD>",
           "dbpush.hosts.0.enable": "true",
           "dbpush.hosts.0.public": "<PRIMARY_IP>",
           "dbpush.hosts.0.internal": "PRIMARY",
           "dbpush.hosts.0.username": "root",
           "dbpush.hosts.0.password": "",
           "dbpush.hosts.0.ssh_port": "22",
           "dbpush.hosts.1.enable": "true",
           "dbpush.hosts.1.public": "<SECONDARY_IP>",
           "dbpush.hosts.1.internal": "SECONDARY",
           "dbpush.hosts.1.username": "root",
           "dbpush.hosts.1.password": "",
           "dbpush.hosts.1.ssh_port": "22"
   }
   ```
4. Save and exit (`Ctrl+x`, `y`, `Enter`).

   > **Tip**
   >
   > This example stores the file in `/root/failover.json`.

### Test the failover configuration

1. Run:

   ```
   sacli --foconf /root/failover.json FailTest
   ```

   - Example output:

     ```
     {
       "connectivity": {
         "friendly": "Connectivity test between primary and secondary nodes succeeded.",
         "message": "SUCCEED: failover connectivity test succeeded",
         "status": true
       },
       "license_primary": {
         "friendly": "Licensed for 2 concurrent connections.",
         "message": "GOOD_LICENSE: Licensed for 2 concurrent connections.",
         "status": true
       },
       "license_secondary": {
         "friendly": "Licensed for 2 concurrent connections.",
         "message": "GOOD_LICENSE: Licensed for 2 concurrent connections.",
         "status": true
       },
       "ucarp": {
         "friendly": "Shared virtual IP address is directly accessible via locally connected interface on both primary and secondary nodes.",
         "message": "UCARP_ADDR_GOOD: ucarp address <FAILOVER_IP> is reachable from locally connected interface on both primary and secondary nodes",
         "status": true
       }
     }
     ```

### Save failover settings

1. Save the failover directives/keys into the database:

   ```
   sacli --key "failover.mode" --value "ucarp" ConfigPut
   sacli --key "ucarp.addr" --value "<FAILOVER_IP>" ConfigPut
   sacli --key "ucarp.secret" --value "<UCARP_PASSWORD>" ConfigPut
   sacli --key "dbpush.hosts.0.enable" --value "true" ConfigPut
   sacli --key "dbpush.hosts.0.public" --value "<PRIMARY_IP>" ConfigPut
   sacli --key "dbpush.hosts.0.internal" --value "PRIMARY" ConfigPut
   sacli --key "dbpush.hosts.0.username" --value "root" ConfigPut
   sacli --key "dbpush.hosts.0.password" --value "" ConfigPut
   sacli --key "dbpush.hosts.0.ssh_port" --value "22" ConfigPut
   sacli --key "dbpush.hosts.1.enable" --value "true" ConfigPut
   sacli --key "dbpush.hosts.1.public" --value "<SECONDARY_IP>" ConfigPut
   sacli --key "dbpush.hosts.1.internal" --value "SECONDARY" ConfigPut
   sacli --key "dbpush.hosts.1.username" --value "root" ConfigPut
   sacli --key "dbpush.hosts.1.password" --value "" ConfigPut
   sacli --key "dbpush.hosts.1.ssh_port" --value "22" ConfigPut
   ```

### Initialize the secondary node

1. Restart Access Server:

   ```
   systemctl restart openvpnas
   ```
2. Wait approximately 10 seconds.
3. Create the `db_push` directory:

   ```
   ssh root@<SECONDARY_IP> "mkdir /usr/local/openvpn_as/etc/db_push/"
   ```
4. Wait approximately 10 seconds.
5. Initialize the secondary node:

   ```
   sacli --foconf=/root/failover.json --init_cmd=restart InitPeer
   ```
6. Verify node state:

   ```
   systemctl status openvpnas | grep "Switching to state:" | tail -n1
   ```

   - Example output of MASTER:

     ```
     [WARNING] Switching to state: MASTER
     ```
   - Example output of BACKUP:

     ```
     [WARNING] Switching to state: BACKUP
     ```

## Step 3: Test failover functionality

### Simulate failover

1. Restart Access Server on the primary node:

   ```
   systemctl restart openvpnas
   ```
2. Wait approximately 10 seconds.
3. Verify node state changes:
   - Primary node should be BACKUP:

     ```
     [WARNING] Switching to state: BACKUP
     ```
   - Secondary node should be MASTER:

     ```
     [WARNING] Switching to state: MASTER
     ```
4. Open the failover IP address in a web browser.
   - The Admin Web UI should now display the secondary node.

### Restore the primary node

1. Restart Access Server on the secondary node:

   ```
   systemctl restart openvpnas
   ```
2. Wait approximately 10 seconds.
3. Verify node state changes:
   - Primary node should be MASTER again:

     ```
     [WARNING] Switching to state: MASTER
     ```
   - Secondary node should be BACKUP again:

     ```
     [WARNING] Switching to state: BACKUP
     ```
4. Open the failover IP address in a web browser.
   - The Admin Web UI should now display the primary node.

## Troubleshooting

To monitor failover state changes, review:

```
/var/log/openvpnas.log
/var/log/openvpnas-node.log
```

---

Prev: [Tutorial: Manage Cluster Settings Using Web API and sacli](https://openvpn.net/as-docs/v3/tutorials/tutorial--manage-cluster-settings-using-the-access-server-cli.md)
Next: [Tutorial: Test and Troubleshoot Access Server Cluster Connectivity](https://openvpn.net/as-docs/v3/tutorials/tutorial--access-server-cluster-connectivity.md)
Index: https://openvpn.net/as-docs/llms.txt
