crowdsecurity/crowdsec · warning
failed to cast machineID to string
Error message
failed to cast machineID to string
What it means
The MachineID claim exists but is not a JSON string, so the assertion rawID.(string) fails and getMachineIDFromContext returns "failed to cast machineID to string". The comment notes this should never happen — it guards against a token whose machine-ID claim is a number, object, or other non-string type.
Source
Thrown at pkg/apiserver/controllers/v1/utils.go:52
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) {
if !option {
return
}
if isUnixSocket(gctx) {
return
}
incomingIP := gctx.ClientIP()
if incomingIP != "127.0.0.1" && incomingIP != "::1" {
gctx.JSON(http.StatusForbidden, gin.H{"message": "access forbidden"})View on GitHub (pinned to 909b515798)
Solutions
- Re-authenticate the machine to obtain a token with a string machine-ID claim
- Fix custom issuing code to store the machine ID as a string: fmt.Sprintf or the original string value
- If you control the claim source, convert numbers with strconv before signing
Example fix
// before
claims[middlewares.MachineIDKey] = machineIntID
// after
claims[middlewares.MachineIDKey] = fmt.Sprintf("%d", machineIntID) Defensive patterns
Strategy: type-guard
Validate before calling
raw, ok := claims[middlewares.MachineIDKey]
if !ok { return errors.New("missing machineID") }
if _, ok := raw.(string); !ok {
return fmt.Errorf("machineID claim must be a string, got %T", raw)
} Type guard
s, ok := rawID.(string)
if !ok { /* token minted with a non-string machine ID; reject */ } Try / catch
machineID, err := getMachineIDFromContext(c)
if err != nil {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"message": "malformed token"})
return
} Prevention
- Always sign the machine ID as a string in custom token-issuing code
- Add a fixture test that decodes issued tokens and asserts claim types
When it happens
Trigger: A JWT whose machine ID claim was signed as a non-string JSON value (e.g. numeric ID or nested object), produced by custom or third-party token-issuing code rather than crowdsec's normal login flow.
Common situations: Hand-rolled token generators serializing the machine ID as a number; corrupted or manipulated tokens; test fixtures with claims built as map[string]interface{}{...: 42}.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- MachineID not found in claims
- failed to extract claims
- token missing required claim
- appsec datasource requires a hub. this is a bug, please repo
- appsec datasource requires a lapi client configuration. this
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/6f398056a0439cba.
Report an issue: GitHub.