Open Source API Gateway

500 Internal Server Error: Cannot Evaluate Rate Limit Key

Membrane API Gateway has an error Cannot evaluate keyExpression … with status 500 Internal Server Error for a rateLimiter whose keyExpression cannot be evaluated. In current versions this error should not occur: the plugin handles evaluation errors itself. If you receive it, it usually indicates a bug in Membrane.

The Error Response

The response contains the status 500 Internal Server Error, the title Internal server error., the detail Cannot evaluate keyExpression '…' cause is … with the expression, the problem type https://membrane-api.io/problems/internal/rate-limit and a link to this page. The type internal means that the gateway could not complete the processing of the exchange, and the subtype rate-limit points to the rate limiter. In production mode, the title is replaced by Internal Server Error, the type is shortened to https://membrane-api.io/problems/internal and the details are left out.

How the Rate Limiter Uses the Key

The rateLimiter counts requests per key. By default the key is the client IP address. With keyExpression, the key is computed from the request, for example from a header or a JSON field, see rate limiting by JWT claim. If the expression cannot be evaluated for a request, Membrane logs a warning and counts the request under the key unknown instead of answering with this error.

Common Causes

An Invalid Key Expression Shows Up Differently

A key expression that fails for some requests does not normally produce this response. Instead, the log contains Error evaluating expression … for rate limit. Fallback to 'unknown', and all affected requests share one counter. Unrelated clients are then limited together.

An Unexpected Error in Membrane

If a response with this error does appear, the evaluation failed in a way the plugin did not handle. This is rare and usually indicates a bug in Membrane.

How to Fix It

  1. If the log shows the Fallback to 'unknown' message, fix the keyExpression so that it evaluates for every request.
  2. If a response with this error does appear, get the details from the response (development mode) or from the log, and report them with your configuration on GitHub Issues.

A key expression that reads a field from the JSON body:

api:
port: 2000
path:
uri: /reset-pwd
flow:
- rateLimiter:
requestLimit: 3
requestLimitDuration: PT30S
language: jsonpath
keyExpression: $.user
target:
url: https://api.predic8.de
api:
  port: 2000
  path:
    uri: /reset-pwd
  flow:
    - rateLimiter:
        requestLimit: 3
        requestLimitDuration: PT30S
        language: jsonpath
        keyExpression: $.user
  target:
    url: https://api.predic8.de

Requests without a user field cannot be keyed by this expression. Validate the body before the rateLimiter if every request must carry the field.

Hide Details in Production

By default, Membrane runs in development mode and adds details to error responses that help you find the problem. These details may reveal information about your setup. In production, turn them off:

configuration:
production: true
configuration:
  production: true

Add the configuration document to your apis.yaml and separate it from the APIs with ---. The title then reads Internal Server Error, and the detail and the link to this page are left out. This error does not add a log key to the response, so look for the log entries at the time of the request.

Related Documentation

Configuration reference:

Tutorials with runnable examples:

← All Membrane error messages

Still stuck? See the troubleshooting guide or ask on GitHub Issues. For commercial support, contact info@predic8.de.