warpdotdev/warp · error
STS AssumeRoleWithWebIdentity failed: {detail}
Error message
STS AssumeRoleWithWebIdentity failed: {detail} What it means
Same STS AssumeRoleWithWebIdentity failure, but on the credential refresh path in bedrock_credentials.rs: it runs when stored Bedrock credentials near expiry and exchanges a web identity token for fresh STS credentials before updating ApiKeyManager (step 3). A failed refresh leaves the manager on the old credentials.
Source
Thrown at app/src/ai/bedrock_credentials.rs:84
let client = sts_client(region).await;
let session_name = aws_role_session_name(task_id);
let sts_creds = client
.assume_role_with_web_identity()
.role_arn(role_arn)
.role_session_name(&session_name)
.web_identity_token(&token.token)
.send()
.await
.map_err(|err| {
let detail = err
.as_service_error()
.map(|e| e.to_string())
.unwrap_or_else(|| err.to_string());
report_error!(
anyhow::Error::new(err)
.context("Bedrock OIDC refresh: STS AssumeRoleWithWebIdentity error")
);
anyhow::anyhow!("STS AssumeRoleWithWebIdentity failed: {detail}")
})?
.credentials
.context("STS response did not include credentials")?;
let aws_creds = AwsCredentials::new(
sts_creds.access_key_id().to_string(),
sts_creds.secret_access_key().to_string(),
Some(sts_creds.session_token().to_string()),
SystemTime::try_from(*sts_creds.expiration()).ok(),
);
// Step 3: Update ApiKeyManager with the fresh credentials.
foreground
.spawn(move |_, ctx| {
ApiKeyManager::handle(ctx).update(ctx, |manager, ctx| {
manager.set_aws_credentials_state(
AwsCredentialsState::Loaded {
credentials: aws_creds,View on GitHub (pinned to e72fd7aacb)
Solutions
- On InvalidIdentityToken-class failures, force a full Bedrock OIDC re-login instead of retrying refresh
- Trigger refresh earlier, before the web identity token's expiry rather than near it
- Add bounded retry with backoff for throttling/transient errors
- Verify system clock sync (NTP) on machines showing repeated refresh failures
Defensive patterns
Strategy: retry
Validate before calling
if token_near_expiry(&oidc_token, margin) {
reauthenticate_oidc().await?; // refresh cannot succeed with a stale token
} Try / catch
match refresh_credentials(&token).await {
Err(e) if e.to_string().contains("STS AssumeRoleWithWebIdentity failed") => {
if is_invalid_token(&e) {
force_full_relogin().await // refresh path is unrecoverable with bad token
} else {
with_backoff(|| refresh_credentials(&token)).await // throttling/transient
}
}
r => r,
} Prevention
- Trigger refresh well before both the OIDC token and STS credential expiries
- Surface refresh failures to prompt re-login instead of silently degrading to old credentials
- Keep system clocks NTP-synced on hosts doing token exchange
When it happens
Trigger: The refresh flow's assume_role_with_webidentity().send() errors: stale OIDC token (long session or clock skew), role/provider changed since login, throttling, or transient STS/network errors (bedrock_credentials.rs:78-88).
Common situations: Refresh scheduled too close to token expiry so the token is already invalid; system clock skew; user's role was removed; intermittent STS availability during refresh windows.
Related errors
- STS AssumeRoleWithWebIdentity failed: {detail}
- invalid value 'integration'
- invalid value 'schedule'
- invalid value 'secret'
- invalid value 'harness-support'
AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16).
Data as JSON: /api/errors/4c96266a266d346a.
Report an issue: GitHub.