Skip to content

Response Rate Limiting forwards requests upstream after quota is exceeded with block_on_first_violation enabled #15036

Description

@subediparas5

Description

The response-ratelimiting plugin continues forwarding requests upstream when the remaining quota becomes negative, even with block_on_first_violation: true.

Kong returns 429 to the client, but only after the request has reached the upstream service. This allows upstream processing to continue after the quota is exhausted.

Environment

  • Kong OSS: 3.9.3
  • Kubernetes: v1.30.0, running on Minikube
  • Deployment: DB-less, one Kong pod with two Nginx workers
  • Counter policy: local

Steps to reproduce

  1. Attach the plugin to a service with this configuration:

    name: response-ratelimiting
    config:
      header_name: X-Kong-Limit
      block_on_first_violation: true
      fault_tolerant: false
      limit_by: ip
      policy: local
      limits:
        requests:
          hour: 5
  2. Configure the upstream to log every request and return:

    X-Kong-Limit: requests=2
  3. Send three sequential requests from the same client, allowing response accounting to complete between requests. These consume six units against the five-unit quota, leaving a remaining quota of -1.

  4. Send two additional requests and inspect both their responses and the upstream logs.

Expected behavior

Once the stored usage reaches or exceeds the quota, Kong should reject subsequent requests with 429 before forwarding them upstream.

Requests already in flight are outside the scope of this issue.

Actual behavior

The additional requests return 429, but both still reach the upstream.

Observed during testing:

Requests Client responses Upstream requests
First three 200, 200, 200 3
Next two 429, 429 2

When usage lands exactly on the limit, early blocking works as expected.

Identified cause

The access-phase check in kong/plugins/response-ratelimiting/access.lua only handles exactly zero remaining quota:

if conf.block_on_first_violation and lv.remaining == 0 then

Negative remaining values bypass this check. Changing the comparison to <= 0 prevented subsequent over-limit requests from reaching upstream in the same Minikube reproduction.

Related discussion

Related to #1096. This report specifically concerns negative remaining quota with block_on_first_violation already enabled, rather than the plugin's default behavior.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions