Open Source API Gateway

500 Internal Server Error: JWT Signing Failed

Membrane API Gateway returns 500 Internal Server Error when the jwtSign plugin cannot create a signed JWT from the message body. The plugin runs in the request or the response flow, depending on where it is placed.

The Error Response

The response contains the status 500 Internal Server Error, the detail Error during attempt to sign JWT payload., the problem type https://membrane-api.io/problems/security and a link to this page. In development mode, the message field contains the underlying error. The type security means that a security plugin failed. In production mode, the title is replaced by Internal Server Error.

What the jwtSign Plugin Does

The jwtSign plugin takes the message body as the claims of a token, adds iat, exp and nbf, signs it with the configured jwk and replaces the body with the JWT. A typical use is a token endpoint:

api:
port: 2000
path:
uri: /token
flow:
- request:
- template:
contentType: application/json
src: |
{
"sub": "user@predic8.de",
"aud": "order"
}

- jwtSign:
jwk:
location: demo.jwk
- return: {}
api:
  port: 2000
  path:
    uri: /token
  flow:
    - request:
        - template:
            contentType: application/json
            src: |
              {
                "sub": "user@predic8.de",
                "aud": "order"
              }
        - jwtSign:
            jwk:
              location: demo.jwk
    - return: {}

Common Causes

The Body Is Not Valid JSON

The message to sign contains XML, text or broken JSON. In the request flow, the client sent it; in the response flow, the backend or a previous plugin produced it.

The Body Is Not a JSON Object

The body is an array, a scalar value or empty. The plugin needs a JSON object to which it can add the time claims.

The Key Has No Private Part

The configured jwk contains only the public key, or it is not an RSA key. Without the private key, the payload cannot be signed.

The Body Cannot Be Read

The body could not be read or decoded, for example because of a broken Content-Encoding.

How to Fix It

  1. Client or backend: send a JSON object as the body of the message that is signed.
  2. Operator: configure jwk with an RSA key that includes the private parts.
  3. Operator: if the claims come from elsewhere, build the JSON object in the flow before jwtSign, for example with template.
  4. Check the log. The exception is logged at error level.

See the JWT tutorial for a complete example of issuing and verifying tokens.

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 ---.

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.