JuliusBrussee/caveman · error
awscreds: no AWS credentials found (env, web identity…
Error message
awscreds: no AWS credentials found (env, web identity, container, IMDS)
What it means
The awscreds Provider walks a chain of credential sources — static env vars, web identity (IRSA/STS), container credentials (ECS/EKS endpoint), and EC2 IMDS. This terminal error means every source returned nothing usable, so no AWS credentials exist in the process and SigV4 signing cannot proceed.
Solutions
- Export AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY (and AWS_SESSION_TOKEN for temporary keys) in the proxy process
- Attach an IAM role: instance profile, ECS task role, or Kubernetes service account with IRSA
- Verify the metadata service is reachable if relying on IMDS (no AWS_EC2_METADATA_DISABLED, no blocked link-local traffic)
- If using Bedrock, consider a Bedrock bearer API key instead of SigV4
Example fix
// before (empty env) $ env | grep AWS_ # nothing // after export AWS_ACCESS_KEY_ID=AKIA... export AWS_SECRET_ACCESS_KEY=...
Defensive patterns
Strategy: validation
Validate before calling
func hasAnyAWSCreds() bool {
if os.Getenv("AWS_ACCESS_KEY_ID") != "" && os.Getenv("AWS_SECRET_ACCESS_KEY") != "" { return true }
if os.Getenv("AWS_WEB_IDENTITY_TOKEN_FILE") != "" { return true }
if os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") != "" || os.Getenv("AWS_CONTAINER_CREDENTIALS_FULL_URI") != "" { return true }
return os.Getenv("AWS_EC2_METADATA_DISABLED") != "true"
}
Try / catch
creds, err := provider.Credentials(ctx)
if err != nil {
if strings.Contains(err.Error(), "no AWS credentials found") {
// fall back to bearer API key or abort with setup guidance
}
return err
}
Prevention
- Attach an IAM role (instance profile, task role, IRSA) in every deployment
- Export static keys for local dev
- Confirm IMDS reachability and that AWS_EC2_METADATA_DISABLED is not set when relying on it
When it happens
Trigger: Calling Credentials() in an environment with no env keys, no web identity token file, no AWS_CONTAINER_CREDENTIALS_RELATIVE/FULL_URI, and no reachable IMDS — e.g. local dev or a container without any role attached.
Common situations: Running the proxy locally outside AWS with no keys exported; Kubernetes pod missing an IRSA annotation; ECS task without a task role; CI runners with no AWS env; firewall blocking 169.254.169.254.
Related errors
- AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must be set…
- awscreds: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must…
- must not contain a newline
- awscreds: AWS_EC2_METADATA_SERVICE_ENDPOINT is not a valid…
- awscreds: build container credentials request
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/864719af3e133fd8.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/awscreds/awscreds.go:274
}
func (p *Provider) fetch(ctx context.Context) (*result, error) {
for _, source := range []func(context.Context) (*result, error){
p.fromEnv, p.fromWebIdentity, p.fromContainer, p.fromIMDS,
} {
res, err := source(ctx)
if err != nil {
return nil, err
}
if res == nil {
continue
}
if !res.creds.Valid() {
return nil, fmt.Errorf("awscreds: %s returned incomplete credentials", res.source)
}
return res, nil
}
return nil, errors.New("awscreds: no AWS credentials found (env, web identity, container, IMDS)")
}
func (p *Provider) env(name string) string { return strings.TrimSpace(p.getenv(name)) }
// fromEnv reads static keys. A half-configured pair is an error, not a skip:
// the operator clearly meant to sign as these keys, and falling through would
// silently sign as whatever ambient role the host carries — a different
// principal, bill, and CloudTrail identity — with no disclosure. A lone
// AWS_SESSION_TOKEN is not a pair and does not trigger this.
func (p *Provider) fromEnv(context.Context) (*result, error) {
access, secret := p.env("AWS_ACCESS_KEY_ID"), p.env("AWS_SECRET_ACCESS_KEY")
if access == "" && secret == "" {
return nil, nil
}
if access == "" || secret == "" {
return nil, errors.New("awscreds: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must both be set")
}
return &result{View on GitHub (pinned to 3ee70a1026)