[httpjson] Rate limiter errors with "the template result is empty" when the remaining header is absent
- Dominant language
- Go
- Stars
- 12.7k
- Forks
- 5k
- Avg merge
- 2d 15m
- Merged PRs (30d)
- 385
Description
## Summary
The `httpjson` input's rate limiter fails with `failed to execute template rate-limit_remaining: the template result is empty` and puts the input into a DEGRADED state when the configured `request.rate_limit.remaining` header is not present in the response.
This contradicts the documented behavior, which states that a missing `remaining` header should simply disable rate-limiting for that response (no error).
## Documented behavior
From the [httpjson input docs](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-input-httpjson.html#_request_rate_limit_remaining):
> `request.rate_limit.remaining`: The value of the response that specifies the remaining quota of the rate limit. It is defined with a Go template value. Can read state from: [`.last_response.header`]. **If the `remaining` header is missing from the Response, no rate-limiting will occur.**
## Actual behavior
When the `remaining` header is missing, the template `[[.last_response.header.Get "X-Rate-Limit-Remaining"]]` evaluates to an empty string. The rate limiter treats this empty template result as a fatal error instead of treating the header as absent, so the input goes DEGRADED with:
> failed to execute template rate-limit_remaining: the template result is empty
## Steps to reproduce
Configure an httpjson input whose `request.rate_limit.remaining` reads a header, and point it at an endpoint that does not always return that header:
```yaml
filebeat.inputs:
- type: httpjson
request.url: https://example.com/api/logs
request.method: GET
request.rate_limit:
limit: '[[.last_response.header.Get "X-Rate-Limit-Limit"]]'
remaining: '[[.last_response.header.Get "X-Rate-Limit-Remaining"]]'
reset: '[[.last_response.header.Get "X-Rate-Limit-Reset"]]'
```
When the response omits `X-Rate-Limit-Remaining`, the input errors and becomes DEGRADED.
## Expected behavior
Per the documentation, when the `remaining` header/value is missing (template result is empty), the rate limiter should skip rate-limiting for that response and continue normally, without erroring or degrading the input.
## Impact / real-world case
This affects the Elastic Okta integration. The Okta System Log API does not always return `X-Rate-Limit-Remaining`, so users deploying via Elastic Agent (e.g. in a Docker container, where the generated `httpjson` config can't be edited to work around it) see the input go DEGRADED. See the reported bug in [elastic/integrations#21027](https://github.com/elastic/integrations/issues/21027).
Contributor guide
Research direction
Start at the httpjson input's rate-limiter handling for request.rate_limit.remaining, using the reproduction configuration and missing X-Rate-Limit-Remaining header described here. Verify the behavior when the template result is empty, then cover the change with the relevant existing rate-limiter tests. Done means the response skips rate-limiting without an error or DEGRADED state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100