langgenius/dify · warning · EmailSendIpLimitError
email_send_ip_limit
email_send_ip_limit
Error message
Too many emails have been sent from this IP address recently. Please try again later.
What it means
Raised as EmailSendIpLimitError (code 'email_send_ip_limit') by POST /email-register/send when AccountService.is_email_send_ip_limit(ip_address) is true — the source IP has triggered too many registration-email sends within the configured window. Prevents email-bombing abuse.
Source
Thrown at api/controllers/console/auth/email_register.py:97
VerificationTokenResponse,
EmailRegisterResetResponse,
)
@console_ns.route("/email-register/send-email")
class EmailRegisterSendEmailApi(Resource):
@setup_required
@email_password_login_enabled
@email_register_enabled
@console_ns.expect(console_ns.models[EmailRegisterSendPayload.__name__])
@console_ns.response(200, "Success", console_ns.models[SimpleResultDataResponse.__name__])
@model_validate(EmailRegisterSendPayload)
def post(self, req_data: EmailRegisterSendPayload):
normalized_email = req_data.email.lower()
ip_address = extract_remote_ip(request)
if AccountService.is_email_send_ip_limit(ip_address):
raise EmailSendIpLimitError()
language = "en-US"
if req_data.language is not None and req_data.language in languages:
language = req_data.language
if dify_config.DEPLOYMENT_EDITION == DeploymentEdition.CLOUD and BillingService.is_email_in_freeze(
normalized_email
):
raise AccountInFreezeError()
account = AccountService.get_account_by_email_with_case_fallback(req_data.email, session=db.session())
token = AccountService.send_email_register_email(email=normalized_email, account=account, language=language)
return {"result": "success", "data": token}
@console_ns.route("/email-register/validity")
class EmailRegisterCheckApi(Resource):
@setup_required
@email_password_login_enabledView on GitHub (pinned to ef8544b173)
Solutions
- Wait for the rate-limit window to elapse before requesting another registration email.
- Throttle the 'resend' button on the client (e.g. 60s cooldown) to avoid tripping the IP limit.
- For NAT'd offices, consider raising the configured IP send-limit or routing registration emails through distinct egress IPs.
- In tests, mock AccountService.send_email_register_email instead of hitting the real endpoint.
Defensive patterns
Strategy: retry
Try / catch
let attempt = 0;
async function sendRegisterEmail(email) {
try {
return await post('/email-register/send', { email });
} catch (e) {
if (e.code === 'email_send_ip_limit') {
// schedule a retry after the rate-limit window; do NOT retry immediately
throw e;
}
throw e;
}
} Prevention
- Client-side cooldown (e.g. 60s) on the 'resend' button to avoid tripping the IP limit.
- For NAT'd offices, plan capacity or use distinct egress IPs for registration flows.
- In tests, mock the email-send service instead of hitting the endpoint.
When it happens
Trigger: POST /console/api/email-register/send issued too many times from the same IP within the rate-limit window (configured in dify_config under email-send IP limits).
Common situations: Multiple users behind one corporate NAT/proxy all registering at once; automated tests hammering the endpoint; a single user repeatedly clicking 'resend'; CI sharing an egress IP across runs.
Related errors
- account_in_freeze
- email_register_limit
- email_already_in_use
- already_activate
- invitation_account_mismatch
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/22ee304c15438fc9.
Report an issue: GitHub.