Description
When multiple POST /config/objects requests are sent concurrently to the Thruk REST API, the internal Perl Storable cache file (Thruk::Utils::Conf, line 754) becomes corrupted. This causes a random subset of objects to be silently dropped — no HTTP error is returned to the caller, yet the objects are never persisted.
Steps to Reproduce
#!/bin/bash
# Reproduces the concurrent /config/objects race condition.
# Sends 300 parallel POST requests, each creating a dummy host object.
# Requires: curl, bash 4+
THRUK_URL="https://localhost/thruk/r"
AUTH_TOKEN="your-api-key"
for i in $(seq 1 300); do
curl -sk \
-H "X-Thruk-Auth-Key: ${AUTH_TOKEN}" \
-H "Content-Type: application/json" \
-X POST "${THRUK_URL}/config/objects" \
-d "{
\":TYPE\": \"host\",
\":FILE\": \"nagios_host.cfg\",
\"host_name\": \"race-test-host-${i}\",
\"alias\": \"Race Test Host ${i}\",
\"address\": \"192.168.99.${i}\",
\"register\": 1
}" \
--output /tmp/race_result_${i}.json &
done
wait
echo "Results:"
for i in $(seq 1 300); do
echo -n " host-${i}: "
cat /tmp/race_result_${i}.json | python3 -c \
"import sys,json; d=json.load(sys.stdin); print(d.get('failed','?'), d.get('message', d.get(':ID','ok')))" \
2>/dev/null || cat /tmp/race_result_${i}.json
done
Observed Behavior
The following errors appear in /var/log/thruk/thruk.log
[ERROR] Magic number checking on storable file failed at .../Thruk/Utils/Conf.pm line 754.
[ERROR] Corrupted storable file (binary v2.11) at .../Thruk/Utils/Conf.pm line 754.
[ERROR] Class name #4 should have been seen already at .../Thruk/Utils/Conf.pm line 754.
[WARN] backend 328c5 returned error: configuration is being parsed right now, try again in a few moments
Only a fraction of the submitted objects are actually created. The remaining requests return HTTP 200 with "created 1 objects successfully." — yet the objects are missing after /config/save.
Expected Behavior
Either:
Concurrent POST /config/objects requests are serialized internally (e.g. via file lock on the Storable cache), so all objects are created correctly, or
The endpoint returns HTTP 409 Conflict or 503 Service Unavailable when a concurrent write is already in progress, so callers can detect the condition and retry
Environment
Thruk version: 3.26
OS: RHEL 8
Naemon version: 1.4.1
Impact
Automation tools that batch-create monitoring objects (e.g. 20 hosts × 54 services/commands = 1080 objects) cannot use any parallelism. With ~0.6 s per sequential request, a single batch job takes ~11 minutes. A server-side batch insert endpoint or internal write serialization would significantly improve usability.
Workaround
Serialize all POST /config/objects calls to a single thread. Resolves the corruption but eliminates parallelism entirely.
Description
When multiple
POST /config/objectsrequests are sent concurrently to the Thruk REST API, the internal Perl Storable cache file (Thruk::Utils::Conf, line 754) becomes corrupted. This causes a random subset of objects to be silently dropped — no HTTP error is returned to the caller, yet the objects are never persisted.Steps to Reproduce
Observed Behavior
The following errors appear in
/var/log/thruk/thruk.logOnly a fraction of the submitted objects are actually created. The remaining requests return HTTP 200 with
"created 1 objects successfully."— yet the objects are missing after/config/save.Expected Behavior
Either:
Concurrent
POST /config/objectsrequests are serialized internally (e.g. via file lock on the Storable cache), so all objects are created correctly, orThe endpoint returns HTTP
409 Conflictor503 Service Unavailablewhen a concurrent write is already in progress, so callers can detect the condition and retryEnvironment
Thruk version: 3.26
OS: RHEL 8
Naemon version: 1.4.1
Impact
Automation tools that batch-create monitoring objects (e.g. 20 hosts × 54 services/commands = 1080 objects) cannot use any parallelism. With ~0.6 s per sequential request, a single batch job takes ~11 minutes. A server-side batch insert endpoint or internal write serialization would significantly improve usability.
Workaround
Serialize all
POST /config/objectscalls to a single thread. Resolves the corruption but eliminates parallelism entirely.