languagetool-org/languagetool · error · TextTooLongException

Your text exceeds the limit of {maxTextLength} characters (i

Error message

Your text exceeds the limit of {maxTextLength} characters (it's {length} characters). Please submit a shorter text.

What it means

LanguageTool server enforces a per-request maximum text length (limits.getMaxTextLength(), default smaller for anonymous users). When the submitted plain-text length exceeds that limit it logs a MAX_TEXT_SIZE metric and throws TextTooLongException (HTTP 413-style) telling the client to submit a shorter text.

Source

Thrown at languagetool-server/src/main/java/org/languagetool/server/TextChecker.java:414

    if (databaseLogger.isLogging()) {
      DatabaseAccess db = DatabaseAccess.getInstance();
      agentId = db.getOrCreateClientId(params.get("useragent"));
      userId = limits.getPremiumUid();
    }
    String referrer = httpExchange.getRequestHeaders().getFirst("Referer");
    String userAgent = httpExchange.getRequestHeaders().getFirst("User-Agent");

    if (!config.isAnonymousAccessAllowed() && limits.getPremiumUid() == null) {
      throw new AuthException("Anonymous access is prohibited on this server, please provide authentication.");
    }

    int length = aText.getPlainText().length();
    if ("true".equals(params.get("languageChanged"))) {
      log.info("languageChanged to " + params.get("language") + " for text with length " + aText.getPlainText().trim().length());
    }
    if (length > limits.getMaxTextLength()) {
      ServerMetricsCollector.getInstance().logRequestError(ServerMetricsCollector.RequestErrorType.MAX_TEXT_SIZE);
      throw new TextTooLongException("Your text exceeds the limit of " + limits.getMaxTextLength() +
              " characters (it's " + length + " characters). Please submit a shorter text.");
    }
    // static because we can't rely on errorRequestLimiter, null when timeoutRequestLimit option not set
    if (!config.isLocalApiMode()) {
      try {
        RequestLimiter.checkUserLimit(referrer, userAgent, limits);
      } catch (TooManyRequestsException e) {
        String response = "Error: Access denied: " + e.getMessage();
        httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_FORBIDDEN, response.getBytes(ENCODING).length);
        httpExchange.getResponseBody().write(response.getBytes(ENCODING));
        String message = "Blocked request from uid:" + userId + " because user limit is reached: ";
        message += "limit = " + limits.getRequestsPerDay() + ", mode = " + limits.getLimitEnforcementMode() + ". ";
        message += "Access from " + remoteAddress + ", ";
        message += "HTTP user agent: " + userAgent + ", ";
        message += "User agent param: " + params.get("useragent") + ", ";
        message += "Referrer: " + referrer + ", ";
        message += "language: " + params.get("language") + ", ";
        message += "h: " + reqCounter.getHandleCount() + ", ";

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Split the text into chunks below the limit and check each chunk separately, merging results
  2. Authenticate with a premium account whose configured maxTextLength is higher
  3. Raise the server's maxTextLength configuration option if you operate the server
  4. Strip unnecessary content (markup, quotes) before submission to reduce length

Example fix

// before
curl -d "text=$(cat bigdoc.txt)" -d language=en-US http://server/v2/check
// after
split -b 19000 bigdoc.txt part_; for f in part_*; do curl -d "text=$(cat $f)" -d language=en-US http://server/v2/check; done
Defensive patterns

Strategy: validation

Validate before calling

const MAX_LEN = 20000; // anonymous default; use your account's limit
if (text.length > MAX_LEN) {
  return chunkText(text, MAX_LEN).map(checkChunk);
}

Try / catch

try {
  return await check(text);
} catch (e) {
  if (e.status === 413 || /exceeds the limit/.test(e.message)) {
    return chunkAndCheck(text, parseLimitFromMessage(e.message));
  }
  throw e;
}

Prevention

When it happens

Trigger: POSTing a text (or data-annotated text) to /v2/check whose getPlainText().length() exceeds the configured limit — e.g. default 20KB anonymous limit or a custom maxTextLength server option — from checkText or its test callers.

Common situations: Pasting whole documents or books into the API, uploading large files, or anonymous clients hitting the smaller anonymous limit while assuming the authenticated (premium) limit applies.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/60190dab0e5e5694. Report an issue: GitHub.