errorsyntaxPOLksef

KSEF-21121:KSeF rate limit reached for this endpoint

Fix: Implement client-side rate limiting with the published per-endpoint quotas, honour the Retry-After header, and stagger bulk workloads across multiple contexts or across time. Do not retry immediately.

KSeF error 21121 ("Limit żądań osiągnięty") is returned when the calling context exceeds the per-endpoint request quota published by the Polish Ministry of Finance. The API rejects the request with HTTP 429 and the client must back off before retrying. Quotas are applied per NIP context, per endpoint, and per time window.

Severity
Fatal
Rule set
ksef
Country
POL
Fix type
BLOCKED
Confidence
90%
Category
rate-limiting

Engine Classification

Financial or legal field · Modification blocked by policy

What is KSEF-21121?

KSEF-21121 is a fatal validation rule defined in the ksef specification (POL national rules). It validates the Sync, and batch endpoints each have their own bucket. The response includes a Retry-After header when a wait time is defined. element under Query > Invoice in the UBL invoice XML.

When this rule fires, the invoice is rejected by Peppol access points and never reaches the buyer.

Target path: The Ministry publishes current limits at https://ksef-test.mf.gov.pl/document/LimitValues/1.3/PL. Limits differ between environments (test vs production) and between endpoints — /online/Session/AuthorisationChallenge, /online/Invoice/Send, /online/Query/Invoice/Sync, and batch endpoints each have their own bucket. The response includes a Retry-After header when a wait time is defined.

This error requires manual correction — financial fields are protected by policy.

Why This Error Matters

Rate-limit failures are silent revenue leaks. Invoices retried aggressively can trigger 21176 (duplicate) or fill your quota so legitimate submissions fail. In the mandatory-KSeF regime, invoices that are not accepted before the buyer's payment window can slow cash collection and cause dispute overhead. Under-provisioned clients also generate support noise that looks like a KSeF outage.

KSEF-21121 is a hard failure — the invoice must be corrected and re-sent before it can reach the recipient.

Delays invoice submission. Does not corrupt data, but chronic 21121 means bookings back up in the ERP and buyer copies are not delivered on time.

Validator Behavior

  • ·Causes invoice rejection
  • ·Error returned: KSEF-21121
  • ·Specification: ksef

How to Fix It

1.

2.

3.

4.

5.

6.

XML Example

Generic example based on the rule's target XPath. Your actual XML structure may differ.

Before
<!-- Triggers validation error -->
<Sync, and batch endpoints each have their own bucket. The response includes a Retry-After header when a wait time is defined.></Sync, and batch endpoints each have their own bucket. The response includes a Retry-After header when a wait time is defined.>
After
<!-- Corrected -->
<Sync, and batch endpoints each have their own bucket. The response includes a Retry-After header when a wait time is defined.>VALID_VALUE</Sync, and batch endpoints each have their own bucket. The response includes a Retry-After header when a wait time is defined.>

Technical Reference

XPathThe Ministry publishes current limits at https://ksef-test.mf.gov.pl/document/LimitValues/1.3/PL. Limits differ between environments (test vs production) and between endpoints — /online/Session/AuthorisationChallenge, /online/Invoice/Send, /online/Query/Invoice/Sync, and batch endpoints each have their own bucket. The response includes a Retry-After header when a wait time is defined.
Specksef
StrategyClient-side backoff and workload shaping. Invoice Navigator queues submissions and paces them under the published limits automatically, so callers do not need to implement per-endpoint token buckets themselves.

Code Example

async function ksefCall(fn, endpoint) {
  await tokenBucket.take(endpoint);
  try {
    return await fn();
  } catch (err) {
    if (err.exceptionCode === 21121) {
      const wait = Number(err.headers['retry-after'] ?? 30);
      await sleep((wait + Math.random() * 5) * 1000);
      return ksefCall(fn, endpoint);
    }
    throw err;
  }
}

Common Causes

  • ·Bulk historical migration hitting /online/Invoice/Send in a tight loop instead of the batch endpoint.
  • ·AuthorisationChallenge called on every request instead of reusing a session token.
  • ·Multiple ERP instances sharing one NIP context without coordinated pacing.
  • ·Retry storm after a transient 5xx — clients retry immediately and stack under the quota window.
  • ·Polling /online/Session/Status too frequently while waiting for session activation.

Seeing this in production? The API handles KSEF-21121 automatically. See the fix response →

Commonly Seen In

All KSeF integrationsiPKO Faktura

Frequently Asked Questions

The Ministry of Finance publishes the authoritative list at https://ksef-test.mf.gov.pl/document/LimitValues/1.3/PL. Limits are per-endpoint and per-NIP context, and change between KSeF versions. Do not hardcode values — pull and cache the published document.

In practical terms, yes — a rejected request is not a submitted invoice. If your ERP does not retry with proper backoff, the invoice can sit undelivered for hours. Under mandatory KSeF this affects VAT booking timelines.

Yes. Invoice Navigator paces submissions under the published quotas per NIP and per endpoint, retries with jitter, and only surfaces a 21121 to your ERP if the burst is genuinely unsustainable (typically >10× your provisioned throughput).

No. Batch endpoints have their own quota and much higher effective throughput per unit of quota. For any workload over ~500 invoices per hour, use /batch/Invoice/Send with Pakiet packaging.

Limits are per NIP context, not per technical user. Adding tokens does not raise your quota. To raise effective throughput, use batch endpoints or split across NIPs where legally permissible (e.g., separate legal entities).

Related Errors

Related Content

Last updated: 28 July 2026

Share this guide:

Validate your invoice

Drop your XML here to check for KSEF-21121

Detect KSEF-21121 before submission

This error involves a financial field that can't be auto-modified. We'll flag it with a clear diagnosis so you can fix it at the source.