paascloud/paascloud-master · error · ValidateCodeException
当天短信发送数上限
Error message
当天短信发送数上限
What it means
checkSendSmsCount finally enforces a global daily SMS quota: it reads totalSmsCountKey from Redis and throws ValidateCodeException('当天短信发送数上限') when the total count exceeds sms.getTotalMaxSendCount(). This caps overall SMS volume for the whole system per day, protecting the SMS provider account from cost overruns and exhaustion.
Solutions
- Raise sms.getTotalMaxSendCount() to match your SMS provider's actual daily plan
- Verify the Redis totalSmsCountKey TTL/reset semantics; consider resetting at midnight if counters drift
- Delete the Redis total key to restore service in an emergency (testing only)
- Alert/monitor on the total counter so ops can raise limits or top up the SMS account before exhaustion
Example fix
// before: default limit too low for prod traffic sms: total-max-send-count: 1000 // after: sized to provider plan sms: total-max-send-count: 100000
Defensive patterns
Strategy: try-catch
Validate before calling
Integer total = (Integer) redisTemplate.opsForValue().get(totalSmsCountKey);
if (total != null && total > totalMaxSendCount) {
// disable send-code UI system-wide
} Try / catch
try {
smsCodeSender.send(mobile);
} catch (ValidateCodeException e) {
alertOps("System-wide SMS daily quota exhausted");
return Result.error(503, "短信服务今日额度已用尽");
} Prevention
- Size totalMaxSendCount to your SMS provider's daily plan with headroom
- Alert on the total counter at e.g. 80% so you can top up the SMS account before exhaustion
- Keep staging and production Redis isolated so test traffic doesn't consume the production quota
- Log which flows consumed the quota to detect abuse or runaway loops
When it happens
Trigger: Any SMS send (send -> checkSendSmsCount) once the system-wide Redis day-counter exceeds smsProperties.getTotalMaxSendCount(); affects all users, not just one mobile or IP.
Common situations: SMS provider quota reached for the day (expected behavior at scale); totalMaxSendCount configured too low for production traffic; a spike/abuse event consumed the daily budget; staging shared Redis with production counters.
Related errors
AI-assisted analysis of paascloud/paascloud-master@781281a950 (2026-09-10).
Data as JSON: /api/errors/80f775f33605f0a3.
Report an issue: GitHub.
Appendix: source
Thrown at paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/validate/code/sms/SmsCodeProcessor.java:130
Integer mobileSmsCount = (Integer) redisTemplate.opsForValue().get(mobileSmsCountKey);
if (mobileSmsCount != null && mobileSmsCount > sms.getMobileMaxSendCount()) {
log.error("Mobile当天短信发送数上限 ipAddr={}, mobile={}", ipAddr, mobile);
throw new ValidateCodeException("Mobile当天短信发送数上限");
} else {
redisTemplate.opsForValue().set(mobileSmsCountKey, mobileSmsCount == null ? 1 : mobileSmsCount + 1, 1, TimeUnit.DAYS);
}
Integer ipSmsCount = (Integer) redisTemplate.opsForValue().get(ipSmsCountKey);
if (ipSmsCount != null && ipSmsCount > sms.getIpMaxSendCount()) {
log.error("IP当天短信发送数上限 ipAddr={}, mobile={}", ipAddr, mobile);
throw new ValidateCodeException("IP当天短信发送数上限");
} else {
redisTemplate.opsForValue().set(ipSmsCountKey, ipSmsCount == null ? 1 : ipSmsCount + 1, 1, TimeUnit.DAYS);
}
Integer totalSmsCount = (Integer) redisTemplate.opsForValue().get(totalSmsCountKey);
if (totalSmsCount != null && totalSmsCount > sms.getTotalMaxSendCount()) {
log.error("当天短信发送数上限 ipAddr={}, mobile={}", ipAddr, mobile);
throw new ValidateCodeException("当天短信发送数上限");
} else {
redisTemplate.opsForValue().set(totalSmsCountKey, totalSmsCount == null ? 1 : totalSmsCount + 1, 1, TimeUnit.DAYS);
}
}
private String getRemoteAddr(HttpServletRequest request) {
String ipAddress = request.getHeader(X_FORWARDED_FOR);
if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader(PROXY_CLIENT_IP);
}
if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader(WL_PROXY_CLIENT_IP);
}
if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (LOCALHOST_IP.equals(ipAddress) || LOCALHOST_IP_16.equals(ipAddress)) {
//根据网卡取本机配置的IP
InetAddress inet = null;View on GitHub (pinned to 781281a950)