Troubleshooting
Connection issues
Section titled “Connection issues”Cannot connect to MikroTik
Section titled “Cannot connect to MikroTik”-
Verify the API service is enabled
/ip/service/print where name=api -
Check the port matches your configuration (default: 8728, TLS: 8729)
-
Verify firewall rules allow access from the bouncer’s IP
-
If using Docker, ensure the container can reach the router network
Authentication failed
Section titled “Authentication failed”-
Verify credentials in your configuration file
-
Check the user exists and has the correct group
/user/print where name=crowdsec -
Verify the user’s group has required policies:
api,read,write -
Check allowed address restrictions on the user account
TLS certificate errors
Section titled “TLS certificate errors”-
For self-signed certificates, set the CA path:
crowdsec:ca_cert_path: "/path/to/ca.pem" -
Verify the certificate is valid and not expired
-
Check the hostname matches the certificate’s CN or SAN
CrowdSec LAPI issues
Section titled “CrowdSec LAPI issues”Cannot connect to LAPI
Section titled “Cannot connect to LAPI”-
Verify the LAPI URL
Terminal window curl http://localhost:8080/v1/decisions -
Check the bouncer API key
Terminal window cscli bouncers list -
If CrowdSec runs in Docker, ensure network connectivity between containers
No decisions received
Section titled “No decisions received”Possible causes:
- No active decisions — check with
cscli decisions list - Origin filtering too restrictive — check
crowdsec.originsconfig - Scenario filtering excludes all — check
crowdsec.scenarios_containing/crowdsec.scenarios_not_containing - CrowdSec engine not detecting threats — check CrowdSec logs
Firewall rule issues
Section titled “Firewall rule issues”Rules not created
Section titled “Rules not created”-
Check filter and raw are enabled
firewall:filter:enabled: trueraw:enabled: true -
Look for errors in logs
Terminal window journalctl -u cs-routeros-bouncer -f -
Verify the user has
writepolicy for firewall operations
Rules are not in the expected position
Section titled “Rules are not in the expected position”-
Verify
rule_placementin configuration. Use"top"for highest priority or"bottom"to append. Use structured placement (position,before_comment,after_comment) when existing router rules must stay first. Check both the global setting and anyfirewall.ipv4.rule_placementorfirewall.ipv6.rule_placementoverride. -
Check for dynamic rules at position 0. The bouncer’s retry logic only applies to
topandposition. It tries lower positions when RouterOS refuses a dynamic or built-in target. -
Check comment anchors for
before_commentandafter_comment. Matching is case-sensitive;comment_match: "contains"is a literal substring match, not a regular expression. -
Inspect positions manually
/ip/firewall/filter print/ip/firewall/raw print -
Check bouncer logs with
journalctl -u cs-routeros-bouncer -f | grep -i placement. Missing comment anchors usefallback(topby default, orbottom). Numeric placement requiresposition; out-of-range numeric positions are appended at the bottom.
Performance issues
Section titled “Performance issues”High CPU during reconciliation
Section titled “High CPU during reconciliation”Performance benchmarks:
| List size | Time | CPU peak | | ----------------------- | --------------------------------------------- | ----------------- | | ~28,700 IPs (full CAPI) | ~58 s wall-clock; ~35–36 s RouterOS bulk work | ~39% observed | | No-drift periodic check | ~3–4 s | Returns near idle |
To reduce impact:
-
Filter synced decisions with
origins:crowdsec:origins: ["crowdsec", "cscli"] -
Schedule bouncer restarts during low-traffic periods
Sustained high RouterOS CPU after startup
Section titled “Sustained high RouterOS CPU after startup”Check for repeated RouterOS API churn:
journalctl -u cs-routeros-bouncer --since "30 min ago" | grep -E "already have such entry|attempting reconnect|RouterOS command failed"Signs of correct behavior (what to look for):
- Cached duplicate ban decisions are skipped without touching RouterOS
- RouterOS
already have such entrydevice errors do not trigger reconnects - Router CPU returns near normal idle/traffic levels after reconciliation finishes
If you still see repeated duplicate errors and reconnect attempts, upgrade to the first release whose changelog includes the RouterOS device-error handling and cache fast-path fixes. Until that release is cut, build from a commit that contains that changelog entry.
Reconciliation timeout or slow startup
Section titled “Reconciliation timeout or slow startup”Large address lists can make startup reconciliation the slowest part of boot. Check whether the logs show bulk script warnings, command timeouts, or pool fallback messages.
Actions to try:
- Increase
mikrotik.command_timeoutfrom its default"30s"to"60s". - Keep
crowdsec.origins: ["crowdsec", "cscli"]on small routers. - Increase
mikrotik.pool_sizefrom its default4only after checking RouterOS APImax-sessions. - Move full CAPI testing to a maintenance window.
mikrotik: command_timeout: "60s" pool_size: 6Duplicate address messages
Section titled “Duplicate address messages”RouterOS can return already have such entry when an address is already present. The bouncer treats this as a device-level duplicate, finds the existing entry, and refreshes timeout/comment when needed. Occasional duplicate messages are harmless.
Repeated duplicate messages every few seconds usually mean the in-memory cache is not matching router state or the service is restarting. Check for restarts, manual address-list edits, and repeated reconciliation failures.
Bulk script fallback warnings
Section titled “Bulk script fallback warnings”During reconciliation, additions are sent in RouterOS scripts of up to 100 entries. If a script fails, the bouncer falls back to individual adds for that chunk and keeps going.
If fallback happens often:
- Check
mikrotik.command_timeout. - Check RouterOS logs for script or policy errors.
- Verify the API user has
read,write,api, andsensitivepolicies. - Test with local-only origins to reduce list size.
IPv6 addresses appear with /128
Section titled “IPv6 addresses appear with /128”RouterOS stores single IPv6 addresses in address lists with an explicit /128 prefix. The bouncer normalizes IPv6 single addresses this way before add, find, and reconciliation operations. This is expected and does not mean CrowdSec sent a range.
Logging and debugging
Section titled “Logging and debugging”logging: level: "debug"Or via environment variable:
LOG_LEVEL=debug cs-routeros-bouncer -c config.ymlcurl http://localhost:2112/healthcurl http://localhost:2112/metrics# View address list entries/ip/firewall/address-list print where list=crowdsec-banned
# Count entries/ip/firewall/address-list print count-only where list=crowdsec-banned
# View bouncer firewall rules/ip/firewall/filter print where comment~"crowdsec-bouncer"/ip/firewall/raw print where comment~"crowdsec-bouncer"Docker-specific issues
Section titled “Docker-specific issues”Container cannot reach router
Section titled “Container cannot reach router”-
Use host networking in Docker Compose:
services:cs-routeros-bouncer:network_mode: host -
Or ensure the Docker network can route to the router’s IP
-
Check DNS resolution if using hostnames
Permission denied for config file
Section titled “Permission denied for config file”-
Check file permissions:
chmod 644 config.yml -
If using Docker secrets, ensure the secret is properly mounted
-
Or use environment variables instead of a config file