Environment
-
Checkmk version: 2.3.0p31 - Raw edition
-
Ruleset affected:
active_checks:httpv2 -
Field affected:
standard_settings.connection.proxy -
Interaction method: REST API (
POST /domain-types/rule/collections/all,PUT /objects/rule/{rule_id})
Summary
When creating or updating an active_checks:httpv2 rule via the REST API with the proxy value format ('url', '<proxy_url>'), the API accepts the request without error (HTTP 200) and stores the rule. However, the resulting rules.mk entry never gets compiled into the monitoring core config (confirmed via cmk -N), so the check silently never runs — with no error, warning, or indication anywhere that something is wrong.
Manually opening the same rule in the WATO GUI and clicking “Save” without changing anything immediately fixes it: the proxy field gets rewritten to the (apparently required) ('cmk_postprocessed', 'explicit_proxy', '<proxy_url>') format, and the check appears in cmk -N right away.
Steps to reproduce
- Create (or update) an
active_checks:httpv2rule via the REST API with a payload containing:
'standard_settings': {
'connection': {
'method': ('get', None),
'http_versions': 'auto',
'proxy': ('url', 'http://httpproxy:3128'),
'redirects': 'follow',
'timeout': 30.0,
},
'server_response': {'expected': [200]},
'content': {},
}
-
API responds
200 OK. No validation error is raised. -
Activate changes via the REST GUI. This also completes successfully with no warnings.
-
On the affected host, run:
cmk -N | grep -i "<the checked url>"-> The check does not appear at all. No error, no pending state visible via this command — it is simply absent from the compiled Nagios config.
-
Open the same rule in Setup → Services → HTTP, HTTPS, TCP, e-mail… → HTTP web service in the GUI, make no changes, click Save, then activate changes.
-
Re-run
cmk -N | grep -i "<the checked url>"→ the check now appears correctly, e.g.:
check_command check_mk_active-httpv2!--url https://mirror.init7.net --method GET --proxy-url http://httpproxy:3128 --onredirect follow --timeout 30 --status-code 200
Root cause (as far as I could determine)
Comparing the raw rules.mk file for the two rules (one created via API only, one resaved once through the GUI) shows the actual stored difference:
Rule created/updated via REST API only (broken — never appears in cmk -N):
'proxy': ('url', 'http://httpproxy:3128')
Same field after being resaved once through the WATO form (working):
'proxy': ('cmk_postprocessed', 'explicit_proxy', 'http://httpproxy:3128')
So:
-
The REST API accepts the plain
('url', <string>)tuple for this field and writes it torules.mkas-is. -
The
GETendpoint on the rule, however, returns the field already normalized to('cmk_postprocessed', 'explicit_proxy', '<url>')— i.e. the API’s read path reconstructs/normalizes the value, while its write path does not perform (or require) the same normalization. This masked the bug for a while during troubleshooting, since comparingGETresponses before/after made the two rules look identical. -
The config compiler for
check_httpv2apparently only recognizes thecmk_postprocessed/explicit_proxyform for this field. A rule stored with the older/plain form is silently skipped at core-config-compile time — no exception, no “invalid rule” warning in the activate-changes result, no discovery/pending-service state to flag it. It just never gets scheduled. -
Only the WATO form’s own
transform_value()step (run on GUI save) performs this migration when writing torules.mk. The REST API endpoints for creating/editing rules do not appear to run the same transform before persisting.
Workaround
Send the proxy field already in the cmk_postprocessed format from the automation script, instead of relying on the API/CMK to migrate it:
standard_settings['connection']['proxy'] = ('cmk_postprocessed', 'explicit_proxy', PROXY_URL)
This produces a rule that is immediately effective without requiring a manual GUI resave.