Description:
Concurrent /config-file load requests via HTTPS API cause the VyOS HTTP API to become unresponsive.
Environment
- VyOS version: 2026.02.03-0027-rolling
- Release train: current
- Architecture: x86_64
- Platform: KVM guest (QEMU, Q35)
- Access method: HTTPS API (
vyos-http-api-server) - API transport: HTTPS (localhost, port 443)
Version Details
vyos@vyos:~$ show version
Version: VyOS 2026.02.03-0027-rolling
Release train: current
Release flavor: generic
Built by: autobuild@vyos.net
Built on: Tue 03 Feb 2026 00:27 UTC
Build UUID: 3e264cbe-8a06-43da-a09c-1abef9dcf34e
Build commit ID: 2c2e8a395073ba
Architecture: x86_64
Boot via: installed image
System type: KVM guest
Secure Boot: n/a (BIOS)
Hardware vendor: QEMU
Hardware model: Standard PC (Q35 + ICH9, 2009)
Hardware S/N:
Hardware UUID: 1fb150d8-2b91-4051-a1f3-b9f56d2497a0
Copyright: VyOS maintainers and contributors
Initial Configuration
Baseline system configuration before reproducing the issue:
interfaces {
ethernet eth0 {
address dhcp
hw-id 52:54:00:bd:ab:83
offload {
gro
gso
sg
tso
}
}
loopback lo {}
}
service {
ntp {
allow-client {
address 127.0.0.0/8
address 169.254.0.0/16
address 10.0.0.0/8
address 172.16.0.0/12
address 192.168.0.0/16
address ::1/128
address fe80::/10
address fc00::/7
}
server time1.vyos.net {}
server time2.vyos.net {}
server time3.vyos.net {}
}
ssh {
port 22
}
}
system {
host-name vyos
login {
user vyos {
authentication {
encrypted-password <redacted>
}
}
}
}
HTTPS API Setup Verification
HTTP API Process Running
ps -ef | grep http
root 4895 1 /usr/share/vyos-http-api-tools/bin/python3 \
/usr/libexec/vyos/services/vyos-http-api-server
API Health Check
curl -k https://127.0.0.1/info
{
"success": true,
"data": {
"banner": "Welcome to VyOS",
"hostname": "vyos",
"version": "2026.02.03-0027-rolling"
},
"error": null
}
Expected Behavior
- The HTTPS API should remain responsive even when multiple configuration load operations are triggered.
- Concurrent
/config-file loadrequests should be safely serialized. - Other API endpoints such as
/infoand/retrieveshould continue responding normally.
Observed Behavior
- When two
/config-file loadoperations are triggered concurrently, the HTTPS API:- Stops responding to requests.
/infoendpoint hangs indefinitely.
- The
vyos-http-api-serverprocess remains running but becomes unresponsive. - No clear error is returned to the client.
- Manual interruption (
Ctrl+C) is required on the client side.
Steps to Reproduce
1. Load configuration file A
curl -k https://127.0.0.1/config-file \
--form data='{"op": "load", "file": "/home/vyos/config-pki-1.boot"}' \
--form key='MY-HTTPS-API-PLAINTEXT-KEY'
Result:
Success
Configuration updated as expected.
2. Load configuration file B
curl -k https://127.0.0.1/config-file \
--form data='{"op": "load", "file": "/home/vyos/config-pki.boot"}' \
--form key='MY-HTTPS-API-PLAINTEXT-KEY'
Result:
Success
Configuration reverts correctly.
3. Trigger concurrent loads (bug trigger)
curl -k https://127.0.0.1/config-file \
--form data='{"op": "load", "file": "/home/vyos/config-pki-1.boot"}' \
--form key='MY-HTTPS-API-PLAINTEXT-KEY' &
curl -k https://127.0.0.1/config-file \
--form data='{"op": "load", "file": "/home/vyos/config-pki.boot"}' \
--form key='MY-HTTPS-API-PLAINTEXT-KEY'
4. Observe API hang
curl -k https://127.0.0.1/info
Result:
No response (hangs indefinitely)
Process State During Failure
ps -ef | grep http
vyos@vyos:~$ ps -ef | grep http
root 4895 1 0 12:57 ? 00:00:04 /usr/share/vyos-http-api-tools/bin/python3 /usr/libexec/vyos/services/vyos-http-api-server
vyos 6493 3589 0 13:12 pts/0 00:00:00 curl -k https://127.0.0.1/config-file --form data={"op": "load", "file": "/home/vyos/config-pki-1.boot"} --form key=MY-HTTPS-API-PLAINTEXT-KEY
vyos 6494 3589 0 13:12 pts/0 00:00:00 curl -k https://127.0.0.1/config-file --form data={"op": "load", "file": "/home/vyos/config-pki.boot"} --form key=MY-HTTPS-API-PLAINTEXT-KEY
The HTTP API server process remains alive but is unresponsive.
Logs During Issue
vyos@vyos:~$ monitor log
Feb 04 13:11:28 vyos-hostsd[748]: Writing /run/pdns-recursor/recursor.vyos-hostsd.conf.lua
Feb 04 13:11:28 vyos-hostsd[748]: Writing /run/pdns-recursor/recursor.forward-zones.conf
Feb 04 13:11:28 vyos-hostsd[748]: pdns_recursor not running, not sending "reload-lua-config"
Feb 04 13:11:28 vyos-hostsd[748]: pdns_recursor not running, not sending "reload-zones"
Feb 04 13:11:28 vyos-hostsd[748]: Success
Feb 04 13:11:28 vyos-hostsd[748]: Saving state to /run/vyos-hostsd/vyos-hostsd.state
Feb 04 13:11:28 vyos-hostsd[748]: Sent response: {'data': {'message': 'Applied 2 changes'}}
Feb 04 13:11:28 dhclient-script-vyos[6351]: No changes to apply via vyos-hostsd-client
Feb 04 13:11:28 dhclient[6245]: bound to 192.168.122.103 -- renewal in 1532 seconds.
Feb 04 13:11:28 dhclient[6245]: bound to 192.168.122.103 -- renewal in 1532 seconds.
Feb 04 13:12:56 vyos-http-api[4895]: processing form data
Feb 04 13:12:56 vyos-http-api[4895]: processing form data
Additional Notes
- The issue appears to be a race condition or missing locking mechanism in the HTTPS API when handling concurrent
/config-file loadoperations. - The system itself does not crash, but the HTTPS API enters a non-recoverable hung state until restarted.
- This behavior makes automation using the HTTPS API unreliable under parallel or concurrent workloads.
Issue Reason and Suggested Fix
Issue Reason
The /config-file API handler in routers.py is implemented as an asynchronous FastAPI endpoint (async def), but it uses a blocking threading.Lock (lock.acquire()) to serialize configuration operations.
Under concurrent /config-file load requests, this can lead to an event-loop deadlock:
- One request acquires the blocking lock and awaits work in a threadpool.
- A subsequent request attempts to acquire the same lock.
- Because
lock.acquire()blocks the event loop, the first coroutine cannot resume and release the lock. - This results in the HTTPS API becoming unresponsive while the process itself remains running.
Suggested Fix
It is recommended to replace the blocking threading.Lock with an asynchronous lock (such as asyncio.Lock) and serialize configuration operations using non-blocking async synchronization.
This approach avoids blocking the event loop, prevents deadlock under concurrent requests, and allows the HTTPS API to remain responsive during parallel configuration operations.
config-pki.boot.txt (8.3 KB)
config-pki-1.boot.txt (8.4 KB)