{"record":{"id":"4bcb5383156de161","repo":"crowdsecurity/crowdsec","slug":"machineid-not-found-in-claims","errorCode":null,"errorMessage":"MachineID not found in claims","messagePattern":"MachineID not found in claims","errorType":"http","errorClass":null,"httpStatus":401,"severity":"error","filePath":"pkg/apiserver/controllers/v1/utils.go","lineNumber":46,"sourceCode":"}\n\nfunc isUnixSocket(c *gin.Context) bool {\n\tif localAddr, ok := c.Request.Context().Value(http.LocalAddrContextKey).(net.Addr); ok {\n\t\treturn strings.HasPrefix(localAddr.Network(), \"unix\")\n\t}\n\n\treturn false\n}\n\nfunc getMachineIDFromContext(ctx *gin.Context) (string, error) {\n\tclaims := jwt.ExtractClaims(ctx)\n\tif claims == nil {\n\t\treturn \"\", errors.New(\"failed to extract claims\")\n\t}\n\n\trawID, ok := claims[middlewares.MachineIDKey]\n\tif !ok {\n\t\treturn \"\", errors.New(\"MachineID not found in claims\")\n\t}\n\n\tid, ok := rawID.(string)\n\tif !ok {\n\t\t// should never happen\n\t\treturn \"\", errors.New(\"failed to cast machineID to string\")\n\t}\n\n\treturn id, nil\n}\n\nfunc (*Controller) AbortRemoteIf(option bool) gin.HandlerFunc {\n\treturn func(gctx *gin.Context) {\n\t\tif !option {\n\t\t\treturn\n\t\t}\n\n\t\tif isUnixSocket(gctx) {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/apiserver/controllers/v1/utils.go#L28-L64","documentation":"After extracting JWT claims, getMachineIDFromContext looks up claims[middlewares.MachineIDKey]; the key is absent when the token was signed without the machine ID claim. The middleware returns \"MachineID not found in claims\", so callers cannot identify which machine issued the request.","triggerScenarios":"A JWT whose payload lacks the MachineIDKey field: tokens minted by an older crowdsec version, hand-crafted tokens in tests, or a login flow that did not pass the machine ID into the jwt payload when signing.","commonSituations":"Mixed-version clusters where an old agent token lacks the claim; custom LAPI login tooling; tokens issued before a crowdsec upgrade changed the claim set.","solutions":["Log the machine in again (cscli machines login / crowdsec LAPI auth) to get a token containing the machine ID claim","Upgrade all agents/bouncers to a version that emits the MachineID claim","Fix custom token-issuing code to include middlewares.MachineIDKey in the jwt payload (see jwt.IdentityHandler / PayloadFunc)","Check that no proxy or shim rewrites or truncates the JWT payload"],"exampleFix":"// before: payload without machine id\nreturn jwt.MapClaims{\"iss\": \"crowdsec\"}\n// after\nreturn jwt.MapClaims{\"iss\": \"crowdsec\", middlewares.MachineIDKey: machineID}","handlingStrategy":"type-guard","validationCode":"claims := jwt.ExtractClaims(c)\nif claims == nil {\n    return errors.New(\"no claims\")\n}\nif _, ok := claims[middlewares.MachineIDKey]; !ok {\n    return errors.New(\"token lacks machineID claim; re-login required\")\n}","typeGuard":"rawID, ok := claims[middlewares.MachineIDKey].(string)\nif !ok || rawID == \"\" { /* invalid token, force re-auth */ }","tryCatchPattern":"machineID, err := getMachineIDFromContext(c)\nif err != nil {\n    c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{\"message\": \"invalid token: re-login the machine\"})\n    return\n}","preventionTips":["Keep agents and LAPI on compatible crowdsec versions so tokens always carry the machine ID claim","Use the official login flow (cscli/crowdsec) rather than hand-crafted JWTs","Validate tokens at login time in staging before rolling upgrades"],"tags":["jwt","claims","machine","lapi"],"backgroundTag":"missing-required-argument","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}