Cron and manual run the same acme.sh line in your paste, so the plugin path is fine; the difference is almost always environment or timing at midnight, not a different challenge type.
Useful checks, in order:
1. Capture one failed cron and one successful manual run with debug still on, and compare the first Cloudflare / dns_cf / TXT error above the exit code 2. That line usually says whether the API token failed, the TXT record was missing, or propagation timed out.
2. Confirm the Cloudflare token in the ACME account still has Zone:DNS:Edit on that zone, and that /var/etc/acme-client/accounts/.../account.conf is readable by the process that cron starts (manual GUI renew sometimes inherits a richer environment).
3. Around 00:00, look in System → Log Files (and any leftover _acme-challenge TXT records in Cloudflare). Leftover TXT from a half-failed run, or CF rate limiting at the top of the hour, both show up as "validation failed" even though a later manual renew works.
4. Shift the ACME auto-renewal window away from 00:00:00 if you can, and verify NTP is synced. Also check you do not have a second cron or external acme.sh --cron fighting the GUI job.
5. For day-to-day debugging: after a failed cron, do not change settings—renew once from the GUI and keep both log blocks. If the only difference is DNS propagation / API errors at night, the workaround of a later schedule is more reliable than chasing permissions that only fail once a day.
If you can paste just the dns_cf / Cloudflare error lines from a failed 00:00 run (redact tokens), it is usually enough to tell API vs propagation apart.
Useful checks, in order:
1. Capture one failed cron and one successful manual run with debug still on, and compare the first Cloudflare / dns_cf / TXT error above the exit code 2. That line usually says whether the API token failed, the TXT record was missing, or propagation timed out.
2. Confirm the Cloudflare token in the ACME account still has Zone:DNS:Edit on that zone, and that /var/etc/acme-client/accounts/.../account.conf is readable by the process that cron starts (manual GUI renew sometimes inherits a richer environment).
3. Around 00:00, look in System → Log Files (and any leftover _acme-challenge TXT records in Cloudflare). Leftover TXT from a half-failed run, or CF rate limiting at the top of the hour, both show up as "validation failed" even though a later manual renew works.
4. Shift the ACME auto-renewal window away from 00:00:00 if you can, and verify NTP is synced. Also check you do not have a second cron or external acme.sh --cron fighting the GUI job.
5. For day-to-day debugging: after a failed cron, do not change settings—renew once from the GUI and keep both log blocks. If the only difference is DNS propagation / API errors at night, the workaround of a later schedule is more reliable than chasing permissions that only fail once a day.
If you can paste just the dns_cf / Cloudflare error lines from a failed 00:00 run (redact tokens), it is usually enough to tell API vs propagation apart.
"