{"record":{"id":"6d26738f64efa3ed","repo":"eclipse-vertx/vert.x","slug":"429-too-many-requests-rfc6585","errorCode":null,"errorMessage":"429 Too Many Requests (RFC6585)","messagePattern":"429 Too Many Requests \\(RFC6585\\)","errorType":"http","errorClass":null,"httpStatus":429,"severity":"warning","filePath":"vertx-core/src/main/java/io/vertx/core/http/HttpResponseExpectation.java","lineNumber":275,"sourceCode":"  /**\n   * 425 Unordered Collection (WebDAV, RFC3648)\n   */\n  HttpResponseExpectation SC_UNORDERED_COLLECTION = status(425);\n\n  /**\n   * 426 Upgrade Required (RFC2817)\n   */\n  HttpResponseExpectation SC_UPGRADE_REQUIRED = status(426);\n\n  /**\n   * 428 Precondition Required (RFC6585)\n   */\n  HttpResponseExpectation SC_PRECONDITION_REQUIRED = status(428);\n\n  /**\n   * 429 Too Many Requests (RFC6585)\n   */\n  HttpResponseExpectation SC_TOO_MANY_REQUESTS = status(429);\n\n  /**\n   * 431 Request Header Fields Too Large (RFC6585)\n   */\n  HttpResponseExpectation SC_REQUEST_HEADER_FIELDS_TOO_LARGE = status(431);\n\n  /**\n   * Any 5XX server error\n   */\n  HttpResponseExpectation SC_SERVER_ERRORS = status(500, 600);\n\n  /**\n   * 500 Internal Server Error\n   */\n  HttpResponseExpectation SC_INTERNAL_SERVER_ERROR = status(500);\n\n  /**\n   * 501 Not Implemented","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/http/HttpResponseExpectation.java#L257-L293","documentation":"SC_TOO_MANY_REQUESTS is an HttpResponseExpectation constant for HTTP 429 (RFC6585). It means the client has sent too many requests in a given time window and the server is rate limiting (often with a Retry-After header). Vert.x exposes it for asserting or reacting to throttling in HttpClient expectations.","triggerScenarios":"Exceeding a server/API rate limit: bursty parallel requests, missing backoff on retries, load tests hitting production, or many concurrent clients sharing one API key/IP. Seen when expecting success but receiving 429, or explicitly with .expecting(SC_TOO_MANY_REQUESTS).","commonSituations":"Runaway retry loops without exponential backoff; integration tests hammering an endpoint; shared egress IP exhausting a quota; third-party API quota changes.","solutions":["Honor the Retry-After header and retry the request after the indicated delay with exponential backoff and jitter.","Reduce request concurrency (batch, debounce, or circuit-breaker) to stay under the limit.","Cache responses or use conditional requests to cut request volume.","Raise the quota with the provider or use a dedicated API key if the shared one is exhausted."],"exampleFix":"// before\nFuture.all(IntStream.range(0, 1000).mapToObj(i -> send(i)).collect(toList()));\n// after\n// retry with backoff on 429\nsendWithRetry(req, attempt -> attempt < 5, delayMs -> delayMs * 2, resp -> resp.statusCode() == 429);","handlingStrategy":"retry","validationCode":"if (inFlightRequests >= rateLimitBudget) {\n  throw new IllegalStateException(\"would exceed rate limit budget\");\n}","typeGuard":"boolean is429(HttpClientResponse resp) { return resp.statusCode() == 429; }","tryCatchPattern":"send().onFailure(err -> {\n  if (isCauseStatus(err, 429)) {\n    long delay = parseRetryAfter(err) orBackoff(attempt);\n    scheduleRetry(delay);\n  }\n});","preventionTips":["Implement exponential backoff with jitter on 429","Honor Retry-After headers","Cap concurrent requests to endpoints with known quotas","Cache responses and use conditional requests to reduce volume"],"tags":["http","rate-limit","retry","vertx-http-client"],"backgroundTag":"rate-limit-exceeded","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}