{"record":{"id":"0a620d6fa69dd386","repo":"xai-org/grok-build","slug":"oidc-expires-in-out-of-range-secs","errorCode":null,"errorMessage":"OIDC expires_in out of range: {secs}","messagePattern":"OIDC expires_in out of range: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-workspace/src/hub_auth/proactive.rs","lineNumber":564,"sourceCode":"            .map_err(refresh_err)?,\n    )\n    .await?\n    .json()\n    .await\n    .map_err(refresh_err)?;\n\n    let now = Utc::now();\n    let (observed_ttl, expires_at) = match tokens.expires_in {\n        Some(secs) => {\n            let ttl = Duration::from_secs(secs);\n            match datetime_plus(now, ttl) {\n                Some(exp) => (Some(ttl), Some(exp)),\n                None => {\n                    // Keep the rotated RT in memory for the next retry, but\n                    // do not persist this failed exchange — a late write\n                    // would clobber a later successful persist.\n                    return Err(RefreshError {\n                        error: anyhow::anyhow!(\"OIDC expires_in out of range: {secs}\"),\n                        new_refresh_token: tokens.refresh_token,\n                        terminal: false,\n                        retry_after: None,\n                    });\n                }\n            }\n        }\n        None => (None, None),\n    };\n    let lead_secs = previous_expires_at.map(|exp| (exp - now).num_milliseconds() as f64 / 1000.0);\n\n    persist_refresh_event(\n        inner,\n        &tokens.access_token,\n        tokens.refresh_token.clone(),\n        expires_at,\n    );\n","sourceCodeStart":546,"sourceCodeEnd":582,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-workspace/src/hub_auth/proactive.rs#L546-L582","documentation":"After a token refresh exchange, the provider parses the OIDC `expires_in` (seconds) into an expiry timestamp. This error is raised as a non-terminal `RefreshError` when `expires_in` is missing or outside the representable/valid range, so no sane expiry can be computed. The rotated refresh token is kept in memory for retry but not persisted, to avoid clobbering a later successful write.","triggerScenarios":"An OIDC token endpoint returns a refresh response whose `expires_in` is absent, zero, negative, or too large to convert into a `chrono::Duration`/future timestamp, during a proactive or on-demand refresh in ProactiveOidcAuthProvider.","commonSituations":"A misbehaving or non-standard OIDC provider/proxy returning malformed token responses; a captive portal or HTML error page parsed as JSON with unexpected fields; clock skew extremes making computed expiry invalid.","solutions":["Retry the operation — the error is marked non-terminal and the rotated refresh token is retained for the next attempt.","Verify the oidc_issuer points at a spec-compliant OIDC provider that returns a numeric `expires_in`.","Check for proxies/interceptors (corporate MITM) mangling the token endpoint response.","Inspect the raw token response with debug logging to see what `expires_in` value was actually returned."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// RefreshError is non-terminal here; retry after a short backoff\nmatch provider.refresh().await {\n    Ok(tokens) => use_tokens(tokens),\n    Err(e) if !e.terminal => {\n        tokio::time::sleep(Duration::from_secs(2)).await;\n        // rotated refresh_token is carried in e.new_refresh_token for the retry\n        provider.refresh().await?;\n    }\n    Err(e) => return Err(e.error),\n}","preventionTips":["Point oidc_issuer at a spec-compliant OIDC provider; avoid hand-rolled token endpoints.","Watch for MITM proxies or captive portals that corrupt token responses.","Keep host clocks NTP-synced so computed expiries stay in range.","Log raw token-endpoint responses when debugging to catch malformed expires_in early."],"tags":["oidc","token-refresh","network","rust"],"backgroundTag":"oidc-token-refresh-failed","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}