JuliusBrussee/caveman · error

awscreds: build sts request

Error message

awscreds: build sts request: %w

What it means

fromWebIdentity builds the AssumeRoleWithWebIdentity POST to the STS endpoint with http.NewRequestWithContext. If request construction itself fails — which practically means the STS endpoint URL is malformed (unparseable scheme/host) or the context is already canceled/invalid — the error is wrapped as "awscreds: build sts request".

Solutions

  1. Print/check the configured STS endpoint; it must be a full absolute URL including scheme (default is https://sts.amazonaws.com or the regional equivalent)
  2. Fix the URL: add https:// if missing, remove placeholders/whitespace, correct the scheme typo
  3. If you don't override the endpoint, remove the override so the built-in default URL is used

Example fix

// before
p := awscreds.New(...) 
p.stsEndpoint = "sts.us-east-1.amazonaws.com" // no scheme -> NewRequest fails
// after
p.stsEndpoint = "https://sts.us-east-1.amazonaws.com"
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(stsEndpoint)
if err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("invalid STS endpoint %q: must be absolute https URL", stsEndpoint)
}

Try / catch

creds, err := awscreds.Credentials(ctx, p)
if err != nil && strings.Contains(err.Error(), "build sts request") {
    return fmt.Errorf("check stsEndpoint config: %w", err)
}

Prevention

When it happens

Trigger: http.NewRequestWithContext(ctx, http.MethodPost, p.stsEndpoint, ...) returns err: stsEndpoint was set (via options/env override) to an invalid URL like "sts.amazonaws.com" without a scheme, or a typo like "httpss://...".

Common situations: Self-hosted/compatible STS endpoint configured incorrectly (missing https://); config templating leaving a placeholder like {{STS_URL}} in the endpoint; trailing garbage in the URL from a config file.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/2e9277646f7ade71. Report an issue: GitHub.

Appendix: source

Thrown at shared/platform/awscreds/awscreds.go:332

	token := strings.TrimSpace(string(raw))
	if token == "" {
		return nil, errors.New("awscreds: web identity token file is empty")
	}
	sessionName := p.env("AWS_ROLE_SESSION_NAME")
	if sessionName == "" {
		sessionName = fmt.Sprintf("caveman-proxy-%d", p.now().Unix())
	}
	form := url.Values{
		"Action":           {"AssumeRoleWithWebIdentity"},
		"Version":          {"2011-06-15"},
		"RoleArn":          {roleARN},
		"RoleSessionName":  {sessionName},
		"WebIdentityToken": {token},
		"DurationSeconds":  {"3600"},
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, p.stsEndpoint, strings.NewReader(form.Encode()))
	if err != nil {
		return nil, fmt.Errorf("awscreds: build sts request: %w", err)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Accept", "application/xml")
	resp, err := p.sts.Do(req)
	if err != nil {
		// A transport error can carry the request URL but never the form body.
		return nil, fmt.Errorf("awscreds: sts assume role with web identity failed: %w", err)
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(io.LimitReader(resp.Body, maxBody))
	if err != nil {
		return nil, fmt.Errorf("awscreds: read sts response: %w", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("awscreds: sts assume role with web identity: http %d%s", resp.StatusCode, stsErrorCode(body))
	}
	var parsed struct {
		XMLName xml.Name `xml:"AssumeRoleWithWebIdentityResponse"`

View on GitHub (pinned to 3ee70a1026)