Repository navigation
15 Troubleshooting
Diagnosis → action → verification. Every recipe here was either reproduced on a test host or follows directly from the code's error messages.
| Symptom | Jump to |
|---|---|
install.sh aborts |
§1 |
fail2ban-client -t fails |
§2 |
| jail is active but reports nothing | §3 |
| bans appear but no AbuseIPDB reports | §4 |
| HTTP 401 | §5 |
| HTTP 429 | §6 |
| HTTP 400/422 | §7 |
| queue grows and never drains | §8 |
| timer does not run | §9 |
| key prompt under systemd | §10 |
| updater refuses to update | §11 |
| false positives / lockout | §12 |
| disk/log growth | §13 |
| need to undo everything | §14 |
Diagnosis. The installer prints the failing step and exits non-zero; backups are in
/var/backups/fail2ban-abuseipdb/pristine-<ts>/.
| Error | Cause | Action |
|---|---|---|
requires root |
not sudo | sudo ./install.sh ... |
python3 >= 3.9 required |
old interpreter | install a newer Python (project is stdlib-only) |
fail2ban-client not found |
fail2ban missing | install fail2ban first |
no API key: pass --api-key ... |
non-interactive run without key | pass the key or run on a terminal |
fail2ban configuration test failed |
the action/jail snippet broke config | installer restores backup; run fail2ban-client -t, read the error |
could not write ... |
permissions/SELinux | run as root; check ls -l on the path |
The installer never restarts fail2ban after a failed -t: if it aborted, the running
configuration is unchanged.
fail2ban-client -tRead the last lines — they name the file and the bad option. Common causes:
- a jail file with a key outside any section;
-
filter = namewith no/etc/fail2ban/filter.d/name.conf; - duplicated keys in the same file (
api_keytwice, etc.); - invalid
actionsyntax in a hand-edited50-abuseipdb-reporter.local.
Action: restore /etc/fail2ban from your backup (or from
/var/backups/fail2ban-abuseipdb/pristine-<ts>/), fix, fail2ban-client -t, then
systemctl restart fail2ban.
fail2ban-client get <jail> actions # is abuseipdb-async attached?
fail2ban-client status <jail> # Currently failed / Total failed / banned-
abuseipdb-asyncmissing → re-run the installer with--jails "<list>"and restart. -
Currently failedgrows butCurrently banned = 0→ threshold not reached orignoreip. -
Currently banned > 0and the queue is empty → check/var/log/abuseipdb-reporter.logforenqueue: ERROR(invalid IP, skip_jails, DB permissions).
grep -i enqueue /var/log/abuseipdb-reporter.log | tail -20
/usr/local/sbin/abuseipdb-report --statsThe pipeline: ban → action → queue → worker → API. Find the first broken link:
# action attached?
fail2ban-client get <jail> actions
# queue receives?
/usr/local/sbin/abuseipdb-report --stats
# worker runs?
systemctl start abuseipdb-report; tail -n 30 /var/log/abuseipdb-reporter.log
# key valid?
/usr/local/sbin/abuseipdb-report --key-status
/usr/local/sbin/abuseipdb-report --check-keyThe log line to look for is reported ip=... -> 200. If it is -> 429, see §6. If there is no
run start line at all, the timer/cron is not running (§9).
- key file empty, wrong content (extra spaces/newlines are stripped, but a wrong key is a wrong key);
- key revoked in the AbuseIPDB account;
- config still pointing at a legacy key that was rotated.
/usr/local/sbin/abuseipdb-report --key-status
/usr/local/sbin/abuseipdb-report --check-keyFix: rewrite /etc/abuseipdb/.abuseipdb.key atomically (mode 600) and run --check-key.
The worker stops on 401 and retries on the next tick — the queue is not lost.
Two distinct cases:
| Response text | Meaning | Behaviour |
|---|---|---|
once in 15 minutes |
same IP reported too recently | event stays pending; retried after the 20-minute throttle |
| daily/global limit | 1000/day plan exhausted | run stops; retries the next day |
Check the counters:
/usr/local/sbin/abuseipdb-report --stats # reports today
grep -c '" -> 429' /var/log/abuseipdb-reporter.logThis is normal under heavy attack. To reduce pressure: lower max_reports_per_day,
raise min_interval_ip (never below 900 s), or add noisy-but-low-value jails to skip_jails.
Usually an invalid timestamp or a comment over the API limit. The reporter truncates to
comment_max_bytes (1000), so 422 is rare. Inspect the exact payload:
/usr/local/sbin/abuseipdb-report --dry-runOpen an issue with the payload (mask the API key if it somehow appears — it should not) and the
log line. Events are marked invalid (reported = 2) and never retried.
/usr/local/sbin/abuseipdb-report --stats
tail -n 100 /var/log/abuseipdb-reporter.log
systemctl status abuseipdb-report.timer| Cause | Evidence | Fix |
|---|---|---|
| worker blocked by lock | log another instance is running repeatedly |
check for a stuck process; remove a stale lock only after confirming |
| API unreachable | timeouts, 5xx | restore egress; queue drains automatically |
| 401 | repeated 401 | fix the key |
| daily budget hit | today=900 |
wait or raise the plan |
| events marked gave up |
gave up (3) > 0 |
inspect the error, then reset those rows if appropriate |
| DB permissions | unable to open database |
chown root:root /var/lib/abuseipdb, mode 700 |
systemctl list-timers abuseipdb-report.timer
systemctl status abuseipdb-report.timer
systemctl status abuseipdb-report.service
journalctl -u abuseipdb-report --since "-1 hour"
cat /etc/cron.d/abuseipdb-reporter
grep CRON /var/log/syslog | tailThe unit may fail if /usr/bin/python3 was removed/upgraded, the config is unreadable, or the
lock directory is not writable. Run the worker manually to see the real error:
/usr/local/sbin/abuseipdb-reportUnder systemd there is no terminal: the worker exits with code 2 and logs
No AbuseIPDB API key found.... Create the key once:
sudo /usr/local/sbin/abuseipdb-report --setup # on a terminal
# or
install -m 600 /dev/stdin /etc/abuseipdb/.abuseipdb.key <<< "KEY"| Error | Cause | Fix |
|---|---|---|
cannot fetch update manifest |
no egress to raw.githubusercontent.com | allow HTTPS or use --manifest-url mirror |
checksum mismatch |
corrupted download / wrong manifest | retry; if it persists, report a security issue — do not bypass |
refusing to update: no sha256 |
broken manifest | wait for a fixed release |
unsafe path in archive |
tampered/broken archive | abort; report |
installer failed |
see §1; key was restored by the updater | inspect installer output |
--upgrade must run as root |
no sudo | sudo abuseipdb-upgrade --upgrade |
exit 10 from --check
|
update available, not an error | run --upgrade
|
If you banned yourself or a legitimate client:
fail2ban-client set <jail> unbanip <addr>
# if SSH is lost, use the provider console / out-of-band accessThen fix the cause:
- add the address to
ignoreipinjail.d/99-whitelist.local; - narrow the filter (see Verification);
- raise
maxretryfor the jail; - check
portscope: a web jail withoutportbans all ports.
Remember: fail2ban-client set ... banip bypasses ignoreip — manual tests are the usual cause.
ls -lh /var/log/abuseipdb-reporter.log /var/lib/abuseipdb/
logrotate -d /etc/logrotate.d/abuseipdb-reporter- log rotation is installed by
install.sh; if the file grows unbounded, check that logrotate runs (/var/lib/logrotate/status); - the SQLite DB is bounded by
retention_days(default 30);--statsshows the journal size; -
/var/backups/fail2ban-abuseipdb/grows per install — prune old pristine directories manually.
# stop reporting and remove the action/code; keep config, queue, key
sudo /path/to/Fail2Ban_AbuseIPDB/install.sh --uninstall
# destroy everything (including the key)
sudo /path/to/Fail2Ban_AbuseIPDB/install.sh --uninstall --purgeUninstall restores files that existed before the first installation and restarts fail2ban. For fail2ban-only rollback see §2.
Next: FAQ · Verification & Rollback · Agent prompts: operations
Fail2Ban_AbuseIPDB · repository · releases · issues · MIT