languagetool-org/languagetool · warning · TooManyRequestsException
Client request size limit of bytes per seconds exceeded in
Error message
Client request size limit of bytes per seconds exceeded in text-level checks
What it means
LanguageTool's server-side RequestLimiter enforces a per-fingerprint request-size quota in Mode.TEXTLEVEL_ONLY. When the bytes sent by one client fingerprint exceed requestLimitInBytes within requestLimitPeriodInSeconds, checkLimit throws TooManyRequestsException (HTTP 429). It protects the text-level-only API from large-volume abuse.
Source
Thrown at languagetool-server/src/main/java/org/languagetool/server/RequestLimiter.java:229
}
}
if (event.fingerprint.equals(fingerprint)) {
requestsByFingerprint++;
requestSizeByFingerprint += event.getSizeInBytes() * modeFactor;
}
if (ipFingerprintFactor > 0 && requestLimit > 0 && requestsByFingerprint > requestLimit) {
String msg = "limit: " + requestLimit + " / " + requestLimitPeriodInSeconds + ", requests: " + requestsByIp + ", ip: " + ipAddress + ", fingerprint: " + fingerprint;
throw new TooManyRequestsException("Client request limit of " + requestLimit + " requests per " +
requestLimitPeriodInSeconds + " seconds exceeded"); }
if (requestLimit > 0 && requestsByIp > ipRequestLimit) {
String msg = "limit: " + ipRequestLimit + " / " + requestLimitPeriodInSeconds + ", requests: " + requestsByIp + ", ip: " + ipAddress + ", fingerprint: " + fingerprint;
throw new TooManyRequestsException("IP request limit of " + ipRequestLimit + " requests per " +
requestLimitPeriodInSeconds + " seconds exceeded");
}
if (event.mode == JLanguageTool.Mode.TEXTLEVEL_ONLY) {
if (ipFingerprintFactor > 0 && requestLimitInBytes > 0 && requestSizeByFingerprint > requestLimitInBytes) {
String msg = "limit in Mode.TEXTLEVEL_ONLY: " + requestLimitInBytes + " / " + requestLimitPeriodInSeconds + ", request size: " + requestSizeByIp + ", ip: " + ipAddress + ", fingerprint: " + fingerprint;
throw new TooManyRequestsException("Client request size limit of " + requestLimitInBytes + " bytes per " +
requestLimitPeriodInSeconds + " seconds exceeded in text-level checks");
}
if (requestLimitInBytes > 0 && requestSizeByIp > ipRequestLimitInBytes) {
String msg = "limit in Mode.TEXTLEVEL_ONLY: " + ipRequestLimitInBytes + " / " + requestLimitPeriodInSeconds + ", request size: " + requestSizeByIp + ", ip: " + ipAddress + ", fingerprint: " + fingerprint;
throw new TooManyRequestsException("IP request size limit of " + ipRequestLimitInBytes + " bytes per " +
requestLimitPeriodInSeconds + " seconds exceeded in text-level checks");
}
} else {
if (ipFingerprintFactor > 0 && requestLimitInBytes > 0 && requestSizeByFingerprint > requestLimitInBytes) {
String msg = "limit: " + requestLimitInBytes + " / " + requestLimitPeriodInSeconds + ", request size: " + requestSizeByIp + ", ip: " + ipAddress + ", fingerprint: " + fingerprint;
throw new TooManyRequestsException("Client request size limit of " + requestLimitInBytes + " bytes per " +
requestLimitPeriodInSeconds + " seconds exceeded");
}
if (requestLimitInBytes > 0 && requestSizeByIp > ipRequestLimitInBytes) {
String msg = "limit: " + ipRequestLimitInBytes + " / " + requestLimitPeriodInSeconds + ", request size: " + requestSizeByIp + ", ip: " + ipAddress + ", fingerprint: " + fingerprint;
throw new TooManyRequestsException("IP request size limit of " + ipRequestLimitInBytes + " bytes per " +
requestLimitPeriodInSeconds + " seconds exceeded");
}View on GitHub (pinned to 2e990059ce)
Solutions
- Wait until requestLimitPeriodInSeconds elapses so the size window resets, then retry with smaller payloads
- Reduce request size: split documents into smaller chunks and/or check less text per request
- Upgrade to a Premium API key (username/apiKey params) which carries higher size limits
- If you operate the server, raise requestLimitInBytes via the server config (e.g. --limitRequestSizeInBytes) or increase requestLimitPeriodInSeconds
- Check for a shared IP/fingerprint (proxy, VPN, corporate NAT) causing aggregation and use a different network or authenticated access
Example fix
// before: checking a huge document in one call POST /v2/check?mode=textLevelOnly body: text=<500KB> // after: chunk the text and add backoff if (clientBytesInWindow + chunk.length > requestLimitInBytes) await sleep(periodRemaining); POST /v2/check?mode=textLevelOnly body: text=<chunk of ~20KB>
Defensive patterns
Strategy: retry
Validate before calling
const bytes = new Blob([params.get('text')]).size;
if (bytes + bytesSentInWindow > REQUEST_LIMIT_BYTES) { await sleep(msUntilWindowReset); } Try / catch
try {
const res = await fetch(url, opts);
if (res.status === 429) { const retryAfter = parseInt(res.headers.get('Retry-After') || '60', 10); await sleep(retryAfter * 1000); return retry(); }
} catch (e) { /* network error handling */ } Prevention
- Track cumulative bytes sent per limit window and stop below the quota
- Chunk large documents instead of sending them whole
- Add exponential backoff on HTTP 429
- Use authenticated (Premium) requests for higher limits
When it happens
Trigger: POSTing text to /v2/check with mode=textLevelOnly (or TEXTLEVEL_ONLY set via param/command line) when the cumulative byte size of requests sharing the same fingerprint (browser/parameter-based, weighted by ipFingerprintFactor) exceeds requestLimitInBytes within the configured requestLimitPeriodInSeconds window.
Common situations: Public API users hitting the free-tier size quota; batch-checking many long documents in a loop without backoff; server misconfigured with too-low 'limitRequestSizeInBytes' style config; shared IPs/fingerprints behind proxies aggregating into one bucket.
Related errors
- IP request size limit of bytes per seconds exceeded in tex
- Client request size limit of bytes per seconds exceeded
- IP request size limit of bytes per seconds exceeded
- User request limit of per day exceeded. Try again after mid
- Whitelist request limit of requests per seconds exceeded
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/2d56cc7491f4f2d2.
Report an issue: GitHub.