zeroclaw-labs/zeroclaw · error
No IAM role attached to this instance
Error message
No IAM role attached to this instance
What it means
The Bedrock provider's from_imds credential path queries EC2 instance metadata (169.254.169.254) for the IAM security-credentials role list. The IMDS endpoint responded (with a valid token), but the role list came back empty, meaning no instance profile is attached, so no credentials can be derived from the instance.
Source
Thrown at crates/zeroclaw-providers/src/bedrock.rs:235
// Step 1: get IMDSv2 token
let token = client
.put("http://169.254.169.254/latest/api/token")
.header("X-aws-ec2-metadata-token-ttl-seconds", "21600")
.send()
.await?
.text()
.await?;
// Step 2: get IAM role name
let role = client
.get("http://169.254.169.254/latest/meta-data/iam/security-credentials/")
.header("X-aws-ec2-metadata-token", &token)
.send()
.await?
.text()
.await?;
let role = role.trim().to_string();
anyhow::ensure!(!role.is_empty(), "No IAM role attached to this instance");
// Step 3: get credentials for that role
let creds_url = format!(
"http://169.254.169.254/latest/meta-data/iam/security-credentials/{}",
role
);
let creds_json: serde_json::Value = client
.get(&creds_url)
.header("X-aws-ec2-metadata-token", &token)
.send()
.await?
.json()
.await?;
let access_key_id = creds_json["AccessKeyId"]
.as_str()
.ok_or_else(|| {
::zeroclaw_log::record!(View on GitHub (pinned to 88bb9c8533)
Solutions
- Attach an IAM instance profile whose role has Bedrock permissions to the instance, then re-run
- For containers on EC2, raise the metadata hop limit: aws ec2 modify-instance-metadata-options --instance-id i-... --http-put-response-hop-limit 2
- Provide explicit credentials instead (AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY or a named profile) and skip IMDS
Example fix
# before: instance without profile aws ec2 associate-iam-instance-profile \ --instance-id i-1234 \ --iam-instance-profile Name=bedrock-runner-role
Defensive patterns
Strategy: fallback
Validate before calling
# probe IMDS for an attached role before relying on it TOKEN=$(curl -sf -X PUT http://169.254.169.254/latest/api/token -H 'X-aws-ec2-metadata-token-ttl-seconds: 60') && \ ROLE=$(curl -sf http://169.254.169.254/latest/meta-data/iam/security-credentials/ -H "X-aws-ec2-metadata-token: $TOKEN") && \ [ -n "$ROLE" ] || echo 'no instance profile — attach one or use explicit credentials' >&2
Try / catch
when constructing the Bedrock provider, try IMDS credentials; on the no-IAM-role error fall back to explicit credentials (environment/profile) before giving up, and log which path succeeded
Prevention
- Attach instance profiles at launch via infrastructure-as-code, not afterwards by hand
- For containerized workloads on EC2 set the metadata hop limit to 2
- Expose AWS credential configuration (env vars/profile) in environments where IMDS is unavailable
When it happens
Trigger: EC2 (or ECS/ECR-based) workload launched without an IAM instance profile; the role was attached in IAM but not as an instance profile on the instance; containers where the metadata hop limit prevents reaching the credentials path so only an empty role list is visible; a non-AWS environment where something else answers on 169.254.169.254.
Common situations: Terraform/CloudFormation templates that create the role but forget the instance-profile association; containers on EC2 needing --http-put-response-hop-limit 2; developers assuming AWS_* env-var-less code will just work on a bare instance.
Related errors
- createSession failed ({status}): {body}
- matrix: configure either `access_token` or `password`
- Nextcloud Talk: no bot secret configured (set bot_token or w
- exceeded {} reconnect attempts, giving up
- xAI OAuth discovery failed ({status}): {body}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/d1f9095622a1952f.
Report an issue: GitHub.