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_enabled

View on GitHub (pinned to ef8544b173)

Solutions

  1. Wait for the rate-limit window to elapse before requesting another registration email.
  2. Throttle the 'resend' button on the client (e.g. 60s cooldown) to avoid tripping the IP limit.
  3. For NAT'd offices, consider raising the configured IP send-limit or routing registration emails through distinct egress IPs.
  4. 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

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


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/22ee304c15438fc9. Report an issue: GitHub.