alibaba/open-code-review · error
bedrock could not authenticate: AWS credentials are expired
Error message
bedrock could not authenticate: AWS credentials are expired or unavailable (%s): %w run `aws sso login%s`, or refresh whichever credential source this profile uses
What it means
explainError (internal/llm/client.go:1124) matches specific AWS credential-failure codes — ExpiredToken, ExpiredTokenException, SSOProviderInvalidToken, InvalidGrantException, NoCredentialProviders, 'failed to refresh cached credentials' — and rewrites them as 'bedrock could not authenticate: AWS credentials are expired or unavailable'. Only exact credential codes match so unrelated 'expired' errors (e.g. TLS cert expiry) are not mislabeled.
Source
Thrown at internal/llm/client.go:1124
return fmt.Errorf("bedrock rejected the token in AWS_BEARER_TOKEN_BEDROCK (%s): %w\n"+
" unset that variable to sign requests with SigV4 instead", where, err)
}
return fmt.Errorf("bedrock rejected an API-key header rather than a signature (%s): %w\n"+
" no api_key applies to bedrock; this means a bearer token reached the request, not that a key is missing", where, err)
case strings.Contains(msg, "don't have access to the model"):
return fmt.Errorf("bedrock has no access enabled for model %q (%s): %w\n"+
" model access is granted per account and per region in the Bedrock console; an IAM policy alone does not enable it", model, where, err)
case strings.Contains(msg, "model identifier is invalid"),
strings.Contains(msg, "inference profile") && strings.Contains(msg, "not found"):
return fmt.Errorf("bedrock rejected model %q (%s): %w\n"+
" run `aws bedrock list-inference-profiles%s` to see what this account offers — IDs are account- and region-scoped, and a version suffix such as -v1:0 is invalid for the newer families",
model, where, err, listProfilesRegionArg(c.awsRegion))
// Specific credential codes only. A bare "expired" would also claim an
// expired TLS certificate is an SSO problem.
case strings.Contains(msg, "ExpiredToken"), strings.Contains(msg, "ExpiredTokenException"),
strings.Contains(msg, "SSOProviderInvalidToken"), strings.Contains(msg, "InvalidGrantException"),
strings.Contains(msg, "NoCredentialProviders"), strings.Contains(msg, "failed to refresh cached credentials"):
return fmt.Errorf("bedrock could not authenticate: AWS credentials are expired or unavailable (%s): %w\n"+
" run `aws sso login%s`, or refresh whichever credential source this profile uses", where, err, ssoLoginProfileArg(c.awsProfile))
// "not authorized to invoke this API operation" is IAM's own wording, so it
// belongs here rather than in the model-access branch above: the fix is a
// policy change, not a console toggle.
case strings.Contains(msg, "AccessDenied"),
strings.Contains(msg, "not authorized to invoke this API operation"):
return fmt.Errorf("bedrock denied access to model %q (%s): %w\n"+
" credentials resolved, so this is an authorization gap: the identity needs bedrock:InvokeModel on this model in this region, and the account needs model access enabled for it", model, where, err)
}
// Everything else — ValidationException on max_tokens, a network reset, a
// throttle — keeps the service's own wording. Guessing at a cause here would
// send people after the wrong problem, which is the failure this function
// exists to prevent.
return fmt.Errorf("bedrock request failed (%s): %w", where, err)
}
func listProfilesRegionArg(region string) string {
if region == "" {View on GitHub (pinned to 5cf97d0d15)
Solutions
- Run `aws sso login` (append `--profile <profile>` if one is active) to mint fresh SSO credentials
- Re-export fresh AWS_ACCESS_KEY_ID/SECRET/SESSION_TOKEN if using static temp credentials
- Run `aws sts get-caller-identity` to confirm credentials now resolve and are valid
- If a credential_process supplies tokens, extend its refresh or re-run it
Example fix
// before # SSO session from yesterday ocr review ... # ExpiredToken // after aws sso login --profile work ocr review ... # succeeds
Defensive patterns
Strategy: retry
Validate before calling
if err := exec.Command("aws", "sts", "get-caller-identity").Run(); err != nil {
exec.Command("aws", "sso", "login").Run()
} Try / catch
_, err := cl.Call(ctx, messages)
if err != nil && strings.Contains(err.Error(), "could not authenticate") {
if err2 := exec.Command("aws", "sso", "login").Run(); err2 == nil {
return retryCall(ctx)
}
return err
} Prevention
- Re-run `aws sso login` daily; SSO sessions expire (typically 12h)
- Refresh temp credentials before jobs expected to outlive their TTL
- Gate long CI jobs behind an `aws sts get-caller-identity` preflight
- Monitor credential-process/SSO expiry and refresh proactively
When it happens
Trigger: A bedrock-runtime InvokeModel call fails at the auth layer because cached SSO credentials expired (default 12h), an assume-role session token timed out, the credential-process returned an expired token, or no provider could produce credentials at request time.
Common situations: Next-day use of a machine whose `aws sso login` from yesterday lapsed; long-running CI job outliving temporary credentials; IAM Identity Center session revoked; STS session from env vars hit its 1-12h limit.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- bedrock rejected the token in AWS_BEARER_TOKEN_BEDROCK (%s):
- bedrock rejected an API-key header rather than a signature (
- bedrock request failed (%s): %w
- llm.protocol cannot be %q: bedrock derives its host from aws
- %s does not apply to provider %q: aws_region and aws_profile
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/f2ee9a5ba1382469.
Report an issue: GitHub.