Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get User endpoint returning wrong rate limit headers #7394

Open
switchupcb opened this issue Feb 16, 2025 · 1 comment
Open

Get User endpoint returning wrong rate limit headers #7394

switchupcb opened this issue Feb 16, 2025 · 1 comment
Labels
bug synced Synced to internal tracker

Comments

@switchupcb
Copy link
Contributor

Description

https://discord.com/api/v10/users/ returns inaccurate rate limit headers.

The response returns a rate limit bucket with a 2000 request limit, then swaps to the rate limit bucket with an accurate rate limit of 30 requests per period.

You can prove that this second rate limit bucket is the accurate rate limit for this request (i.e. Get User) because there are tests — which have handled this limit for multiple years correctly — which queue over 30 Get User requests to test the handling of Discord Route Rate Limits.

Steps to Reproduce

This test has not changed in two years with the exception of increased request timeouts, which represents the amount of time a request waits for a response.

Both result in the same behavior described.

Here is the human readable steps to reproduce this issue.

  1. Send a Get User request.
  2. Use rate limit headers to send more Get User requests according to the specified rate limit.
  3. Receive an HTTP 429 response before the bot has exhausted the rate limit specified during steps 1 and 2.

Expected Behavior

The rate limits headers are accurate.

Current Behavior

Here is the current behavior which shows

  1. the request prior to the 429 HTTP response with headers X-Ratelimit-Bucket: 06f50622af95a11ccfb8304b866ed5b0\r\nX-Ratelimit-Limit: 2000\r\nX-Ratelimit-Remaining: 1980.
  2. the request with a 429 HTTP response with headers X-Ratelimit-Bucket: 481e0bf1883da82f2e83411bc2da9c89\r\nX-Ratelimit-Limit: 30\r\nX-Ratelimit-Remaining: 0.
{
    "level": "info",
    "time": "2025-02-15T21:24:48.4587733-06:00",
    "client": "",
    "request": {
        "xid": "cuolkvv5ohdj087k30e0",
        "route": "178",
        "resource": "",
        "endpoint": "https://discord.com/api/v10/users/990803528735932476"
    },
    "response": {
        "header": "HTTP/1.1 200 OK\r\nServer: cloudflare\r\nDate: Sun, 16 Feb 2025 03:24:47 GMT\r\nContent-Type: application/json\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nStrict-Transport-Security: max-age=31536000; includeSubDomains; preload\r\nX-Ratelimit-Bucket: 06f50622af95a11ccfb8304b866ed5b0\r\nX-Ratelimit-Limit: 2000\r\nX-Ratelimit-Remaining: 1980\r\nX-Ratelimit-Reset: 1739676288.766\r\nX-Ratelimit-Reset-After: 0.573\r\nVary: Accept-Encoding\r\nVia: 1.1 google\r\nAlt-Svc: h3=\":443\"; ma=86400\r\nCf-Cache-Status: BYPASS\r\nReport-To: {\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=zJB8V4hGmhuuq%2FI8PQJ%2BMXPTuEHjfYiZXYvyYZbH3zfWrTpESSrVLId9FoPOy%2FAov3KEERaiO1XfEBdOCeuqd505vxzGgLDftNdLk7GwLDixjsO5UML%2FUtkl3%2B3y\"}],\"group\":\"cf-nel\",\"max_age\":604800}\r\nNel: {\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}\r\nX-Content-Type-Options: nosniff\r\nReporting-Endpoints: csp-sentry=\"https://o64374.ingest.sentry.io/api/5441894/security/?sentry_key=8fbbce30bf5244ec9429546beef21870&sentry_environment=stable\"\r\nContent-Security-Policy: frame-ancestors 'none'; default-src https://o64374.ingest.sentry.io; report-to csp-sentry; report-uri https://o64374.ingest.sentry.io/api/5441894/security/?sentry_key=8fbbce30bf5244ec9429546beef21870&sentry_environment=stable\r\nCf-Ray: 912a6d409e136b28-DFW\r\nSet-Cookie: __dcfduid=9353bed0ec1511efac16621e9a5eced7; Expires=Fri, 15-Feb-2030 03:24:48 GMT; Max-Age=157680000; Secure; HttpOnly; Path=/; SameSite=Lax\r\nSet-Cookie: __sdcfduid=9353bed0ec1511efac16621e9a5eced75fe455f6d64a479c7ab42c8b932a04e79b34eaa1e37f50ad6c43efe94abd9d80; Expires=Fri, 15-Feb-2030 03:24:48 GMT; Max-Age=157680000; Secure; HttpOnly; Path=/; SameSite=Lax\r\nSet-Cookie: __cfruid=2b175f63f811e215849f19f1df67bfd9f39e6da5-1739676288; path=/; domain=.discord.com; HttpOnly; Secure; SameSite=None\r\nSet-Cookie: _cfuvid=HOF6rpJVgjW9ishjcOXvq.0h1z9ga4zGgTR3GuaazO0-1739676288226-0.0.1.1-604800000; path=/; domain=.discord.com; HttpOnly; Secure; SameSite=None\r\n\r\n",
        "body": "{\"id\":\"990803528735932476\",\"username\":\"Disgo\",\"avatar\":null,\"discriminator\":\"0521\",\"public_flags\":0,\"flags\":0,\"bot\":true,\"banner\":null,\"accent_color\":null,\"global_name\":null,\"avatar_decoration_data\":null,\"banner_color\":null,\"clan\":null,\"primary_guild\":null}\n"
    }
}
{
    "level": "info",
    "time": "2025-02-15T21:24:48.4797313-06:00",
    "client": "",
    "request": {
        "xid": "cuolkvv5ohdj087k30g0",
        "route": "178",
        "resource": "",
        "endpoint": "https://discord.com/api/v10/users/990803528735932476"
    },
    "response": {
        "header": "HTTP/1.1 429 Too Many Requests\r\nServer: cloudflare\r\nDate: Sun, 16 Feb 2025 03:24:47 GMT\r\nContent-Type: application/json\r\nContent-Length: 80\r\nConnection: keep-alive\r\nRetry-After: 30\r\nX-Ratelimit-Scope: user\r\nStrict-Transport-Security: max-age=31536000; includeSubDomains; preload\r\nX-Ratelimit-Bucket: 481e0bf1883da82f2e83411bc2da9c89\r\nX-Ratelimit-Limit: 30\r\nX-Ratelimit-Remaining: 0\r\nX-Ratelimit-Reset: 1739676317.636\r\nX-Ratelimit-Reset-After: 29.320\r\nVia: 1.1 google\r\nAlt-Svc: h3=\":443\"; ma=86400\r\nCf-Cache-Status: BYPASS\r\nReport-To: {\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=X4X9ltfzw9b3U%2BZSSrUTdlnMtEEl8Lezn0qGZ%2Bx3g83DC%2B5eW7rUCKvvPHi90oQLM03I5HZCSmkjHmN8S4OkwFmnPkiWA4Q36FC%2FHGm670S2715qzTOD5jtCZDxk\"}],\"group\":\"cf-nel\",\"max_age\":604800}\r\nNel: {\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}\r\nX-Content-Type-Options: nosniff\r\nReporting-Endpoints: csp-sentry=\"https://o64374.ingest.sentry.io/api/5441894/security/?sentry_key=8fbbce30bf5244ec9429546beef21870&sentry_environment=stable\"\r\nContent-Security-Policy: frame-ancestors 'none'; default-src https://o64374.ingest.sentry.io; report-to csp-sentry; report-uri https://o64374.ingest.sentry.io/api/5441894/security/?sentry_key=8fbbce30bf5244ec9429546beef21870&sentry_environment=stable\r\nCf-Ray: 912a6d409e8f6b2e-DFW\r\nSet-Cookie: __dcfduid=9365cefeec1511ef8db4ea765ce5924d; Expires=Fri, 15-Feb-2030 03:24:48 GMT; Max-Age=157680000; Secure; HttpOnly; Path=/; SameSite=Lax\r\nSet-Cookie: __sdcfduid=9365cefeec1511ef8db4ea765ce5924d8d3961230b87e1e1defd63a60e2ae503fc7e048d7c9422c67e83d07d4c80bfd5; Expires=Fri, 15-Feb-2030 03:24:48 GMT; Max-Age=157680000; Secure; HttpOnly; Path=/; SameSite=Lax\r\nSet-Cookie: __cfruid=2b175f63f811e215849f19f1df67bfd9f39e6da5-1739676288; path=/; domain=.discord.com; HttpOnly; Secure; SameSite=None\r\nSet-Cookie: _cfuvid=ikdPYMySeqmQTIq5QmstGwzr9uXP0gYXFkR951cjOqs-1739676288341-0.0.1.1-604800000; path=/; domain=.discord.com; HttpOnly; Secure; SameSite=None\r\n\r\n",
        "body": "{\"message\": \"You are being rate limited.\", \"retry_after\": 0.32, \"global\": false}"
    }
}

Screenshots/Videos

No response

Client and System Information

See test and current behavior.

@switchupcb switchupcb added the bug label Feb 16, 2025
@appellation appellation added the synced Synced to internal tracker label Feb 21, 2025
@gXLg
Copy link

gXLg commented Feb 22, 2025

I want to confirm this, running into exactly the same issue (except that it's in JS).

Original Post on Discord:

I am writing a discord API library and currently reworking my rate-limit setup. For testing, I ran

while (true) {
  await bot.request();
}

For some reason, the reported rate-limit buckets are wrong. I print the current bucket for each request and how many more requests are remaining in there.
If I get rate-limited, then I print some more information.

Weird things:

  1. The "remaining" value never changes and stays pretty high (1999), which I could explain, because the "reset-after" for this bucket is very low (~0.3 seconds)
  2. Once I've hit somewhere around 35 requests, the bucket ID suddenly changes to another and reports "remaning == 0"
  3. The 429 response contains the header "retry-after" and a field in the JSON body "retry_after", which have two completely different values!
  4. Once I wait the amount of time, specified in the "retry-after" header, the bucket ID switches back to the old one

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug synced Synced to internal tracker
Projects
None yet
Development

No branches or pull requests

3 participants