{"record":{"id":"32abe92516f04ac6","repo":"AlistGo/alist","slug":"invalid-token-w","errorCode":null,"errorMessage":"invalid token: %w","messagePattern":"invalid token: %w","errorType":"http","errorClass":null,"httpStatus":401,"severity":"error","filePath":"server/mcp/auth.go","lineNumber":70,"sourceCode":"\t// No token: guest\n\tif token == \"\" {\n\t\tguest, err := op.GetGuest()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to get guest: %w\", err)\n\t\t}\n\t\tif guest.Disabled {\n\t\t\treturn nil, fmt.Errorf(\"guest user is disabled\")\n\t\t}\n\t\tif err := loadRoles(guest); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn guest, nil\n\t}\n\n\t// JWT token\n\tclaims, err := common.ParseToken(token)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid token: %w\", err)\n\t}\n\n\tuser, err := op.GetUserByName(claims.Username)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"user not found: %w\", err)\n\t}\n\n\tif claims.PwdTS != user.PwdTS {\n\t\treturn nil, fmt.Errorf(\"password has been changed\")\n\t}\n\tif user.Disabled {\n\t\treturn nil, fmt.Errorf(\"user is disabled\")\n\t}\n\n\tif err := loadRoles(user); err != nil {\n\t\treturn nil, err\n\t}\n\treturn user, nil","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/server/mcp/auth.go#L52-L88","documentation":"Returned by authenticateToken (server/mcp/auth.go:70) when the presented MCP token is neither the admin static token nor empty, so it is parsed as a JWT by common.ParseToken and that fails. Typical wrapped causes: expired token, signature made by a different JWTSecret, or malformed token text.","triggerScenarios":"MCP client sends an expired login token; the server's JWT secret changed (reinstall, new secret env var, multi-replica cluster with divergent secrets); token from a different OpenList instance.","commonSituations":"Long-running MCP sessions whose token outlives its expiry; servers regenerated after config loss; tokens cached in tooling across environment rebuilds.","solutions":["Obtain a fresh token via the login endpoint and update the MCP client config","If the secret was intentionally rotated, expect all old tokens to fail — reissue them","In clustered setups, ensure every replica shares the same JWT secret","Inspect the wrapped error to distinguish 'expired' from 'signature is invalid'"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"invalid token\") { token = refreshViaLogin(); retryOnce() }","preventionTips":["Automate token refresh before expiry in long-lived MCP clients","Share one JWT secret across all replicas","Never reuse tokens between instances"],"tags":["mcp","auth","jwt","token-expiry"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}