crowdsecurity/crowdsec · error

failed to extract claims

Error message

failed to extract claims

What it means

getMachineIDFromContext reads the JWT claims extracted by the gin-jwt middleware via jwt.ExtractClaims(ctx). It returns "failed to extract claims" when ExtractClaims returns nil, i.e. the request carries no usable JWT claim payload — typically because the JWT middleware never validated a token for this request.

Source

Thrown at pkg/apiserver/controllers/v1/utils.go:41

	if !ok {
		return nil, errors.New("bouncer not found")
	}

	return bouncerInfo, nil
}

func isUnixSocket(c *gin.Context) bool {
	if localAddr, ok := c.Request.Context().Value(http.LocalAddrContextKey).(net.Addr); ok {
		return strings.HasPrefix(localAddr.Network(), "unix")
	}

	return false
}

func getMachineIDFromContext(ctx *gin.Context) (string, error) {
	claims := jwt.ExtractClaims(ctx)
	if claims == nil {
		return "", errors.New("failed to extract claims")
	}

	rawID, ok := claims[middlewares.MachineIDKey]
	if !ok {
		return "", errors.New("MachineID not found in claims")
	}

	id, ok := rawID.(string)
	if !ok {
		// should never happen
		return "", errors.New("failed to cast machineID to string")
	}

	return id, nil
}

func (*Controller) AbortRemoteIf(option bool) gin.HandlerFunc {
	return func(gctx *gin.Context) {

View on GitHub (pinned to 909b515798)

Solutions

  1. Ensure the JWT auth middleware runs and aborts unauthorized requests before these handlers
  2. Re-authenticate the machine with `cscli machines add` / crowdsec LAPI login to obtain a fresh token
  3. Verify the Authorization: Bearer header survives any proxy between agent and LAPI
  4. In tests, seed the gin context with valid claims or run the auth middleware first

Example fix

// before: handler reachable without auth
r.POST("/alerts", ctrl.CreateAlert)
// after
r.POST("/alerts", jwtMiddleware.MiddlewareFunc(), ctrl.CreateAlert)
Defensive patterns

Strategy: try-catch

Validate before calling

hdr := c.GetHeader("Authorization")
if !strings.HasPrefix(hdr, "Bearer ") || len(hdr) < 20 {
    // request will not yield claims; reject early or force re-login
}

Type guard

claims := jwt.ExtractClaims(c)
if claims == nil { /* token missing or invalid — redirect to re-auth */ }

Try / catch

machineID, err := getMachineIDFromContext(c)
if err != nil {
    c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"message": "authentication required"})
    return
}

Prevention

When it happens

Trigger: Handlers CreateAlert, HeartBeat, DeleteMachine, PrometheusMachinesMiddleware or UsageMetrics are reached without a validated machine JWT: missing/expired Authorization header, token rejected upstream but the request not aborted, or direct handler invocation in tests.

Common situations: A machine client whose token expired mid-request-batch; a reverse proxy stripping the Authorization header; calling LAPI endpoints with an API key instead of a machine JWT; unit tests calling handlers without authMiddleware.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/72a0827d8037484c. Report an issue: GitHub.