{
  "id": "api/oauth2-invalid-grant-refresh-token-expired",
  "signature": "OAuth2 error: invalid_grant — refresh token expired or revoked",
  "signature_zh": "OAuth2 错误：invalid_grant — 刷新令牌已过期或已被撤销",
  "regex": "(?:OAuth2 error|invalid_grant)[\\s:]*(?:refresh token|RefreshToken).*(?:expired|revoked|invalid)",
  "domain": "api",
  "category": "auth_error",
  "subcategory": null,
  "root_cause": "The refresh token used to obtain a new access token has been revoked, expired, or used beyond its rotation limit, causing the authorization server to reject the grant.",
  "root_cause_type": "generic",
  "root_cause_zh": "用于获取新访问令牌的刷新令牌已被撤销、过期或超出轮换限制，导致授权服务器拒绝授权。",
  "versions": [
    {
      "version": "OAuth 2.0 (RFC 6749)",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Google OAuth 2.0 (2023+)",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Auth0 OIDC (2024)",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "",
      "why_fails": "The token is already expired or revoked; reusing it will still fail.",
      "fail_rate": 0.9,
      "condition": "",
      "sources": []
    },
    {
      "action": "",
      "why_fails": "The underlying issue (e.g., token rotation limit or revocation) persists, causing the new refresh token to fail again.",
      "fail_rate": 0.7,
      "condition": "",
      "sources": []
    },
    {
      "action": "",
      "why_fails": "The error is a permanent grant rejection, not a transient network issue; retries will not succeed.",
      "fail_rate": 0.8,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "Implement refresh token rotation: after each successful token refresh, invalidate the old refresh token and issue a new one. In code, use a library like `oauthlib` or `google-auth` that handles rotation automatically. Example: `credentials.refresh(request)` with `google.oauth2.credentials`.",
      "success_rate": 0.85,
      "how": "Implement refresh token rotation: after each successful token refresh, invalidate the old refresh token and issue a new one. In code, use a library like `oauthlib` or `google-auth` that handles rotation automatically. Example: `credentials.refresh(request)` with `google.oauth2.credentials`.",
      "condition": "",
      "sources": []
    },
    {
      "action": "Store refresh tokens securely and monitor their expiration. If the error occurs, prompt the user to re-authenticate via the full OAuth flow. Example: catch `RefreshError` and redirect to the authorization endpoint.",
      "success_rate": 0.9,
      "how": "Store refresh tokens securely and monitor their expiration. If the error occurs, prompt the user to re-authenticate via the full OAuth flow. Example: catch `RefreshError` and redirect to the authorization endpoint.",
      "condition": "",
      "sources": []
    },
    {
      "action": "Check if the refresh token has been revoked by inspecting the authorization server's token introspection endpoint. Example: `POST /introspect` with `token=<refresh_token>` and `token_type_hint=refresh_token`.",
      "success_rate": 0.8,
      "how": "Check if the refresh token has been revoked by inspecting the authorization server's token introspection endpoint. Example: `POST /introspect` with `token=<refresh_token>` and `token_type_hint=refresh_token`.",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "实现刷新令牌轮换：每次成功刷新令牌后，使旧刷新令牌失效并颁发新令牌。使用像 `oauthlib` 或 `google-auth` 这样的库自动处理轮换。示例：`credentials.refresh(request)` 配合 `google.oauth2.credentials`。",
    "安全存储刷新令牌并监控其过期时间。如果出现此错误，提示用户通过完整的 OAuth 流程重新认证。示例：捕获 `RefreshError` 并重定向到授权端点。",
    "通过检查授权服务器的令牌内省端点来验证刷新令牌是否被撤销。示例：`POST /introspect` 参数 `token=<refresh_token>` 和 `token_type_hint=refresh_token`。"
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2",
  "official_doc_section": null,
  "error_code": "invalid_grant",
  "verification_tier": "ai_generated",
  "confidence": 0.85,
  "fix_success_rate": 0.85,
  "resolvable": "true",
  "first_seen": "2024-03-15",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}