kubernetes/kops · error
url not valid for STS request
Error message
url not valid for STS request
What it means
The presigned STS URL comes from an untrusted token, so isValidV2 enforces a strict shape before the verifier will contact it: https scheme, host equal to the configured STS host, path "/", and exactly one Action=GetCallerIdentity query parameter. Any deviation — including an http:// URL that would leak the request in plaintext — triggers this error, preventing SSRF and downgrade attacks.
Source
Thrown at pkg/bootstrap/awsbootstrap/verifier.go:403
if u.Query().Get("Action") != "GetCallerIdentity" {
return false
}
if len(u.Query()["Action"]) != 1 {
return false
}
return true
}
// getCallerIdentityV2 will request the presigned token URL, and decode the returned identity.
func (s *stsRequestValidator) getCallerIdentityV2(ctx context.Context, httpClient *http.Client, decoded *awsV2Token) (*GetCallerIdentityResponse, error) {
reqURL, err := url.Parse(decoded.URL)
if err != nil {
return nil, fmt.Errorf("parsing STS request URL: %w", err)
}
if !s.isValidV2(reqURL) {
return nil, fmt.Errorf("url not valid for STS request")
}
req := &http.Request{
URL: reqURL,
Method: decoded.Method,
Header: decoded.SignedHeader,
}
response, err := httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("sending STS request: %v", err)
}
if response != nil {
defer response.Body.Close()
}
responseBody, err := io.ReadAll(response.Body)
if err != nil {
return nil, fmt.Errorf("reading STS response: %v", err)View on GitHub (pinned to 4c8573c808)
Solutions
- Regenerate the presigned URL with the AWS SDK against the STS endpoint matching the verifier's configured stsRequestValidator.Host (same region), using https.
- Ensure the presign uses the standard SDK Presign (GetCallerIdentity, GET) rather than hand-rolled URL construction.
- Compare the URL host on the failing token with s.Host to confirm region/endpoint mismatch, then align client region config.
- If tokens are proxied, verify no component rewrites scheme, host, path, or duplicates the Action query parameter.
Example fix
// Client-side presign must target the verifier's STS host over https:
// before (hand-built, wrong region/scheme)
url := "http://sts.us-east-1.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&..."
// after
req, _ := stsclient.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
presigned, _ := stsclient.PresignGetCallerIdentity(ctx, req,
sts.WithPresignClient(presignClient)) // https, correct region, Action=GetCallerIdentity Defensive patterns
Strategy: try-catch
Validate before calling
u, err := url.Parse(token.URL)
if err != nil { return err }
valid := u.Scheme == "https" &&
u.Host == expectedSTSHost &&
u.Path == "/" &&
u.Query().Get("Action") == "GetCallerIdentity" &&
len(u.Query()["Action"]) == 1
if !valid { return fmt.Errorf("presigned URL host/scheme/action mismatch: host=%s scheme=%s", u.Host, u.Scheme) } Type guard
func isWellFormedPresignedSTSURL(raw, expectedHost string) bool {
u, err := url.Parse(raw)
if err != nil { return false }
return u.Scheme == "https" && u.Host == expectedHost && u.Path == "/" &&
u.Query().Get("Action") == "GetCallerIdentity" && len(u.Query()["Action"]) == 1
} Try / catch
result, err := verifier.VerifyToken(ctx, token)
if err != nil && strings.Contains(err.Error(), "url not valid for STS request") {
// client presigned against wrong region/endpoint or http; re-presign on the node
return nil, fmt.Errorf("check node's AWS region config and STS endpoint; regenerate token: %w", err)
} Prevention
- Presign GetCallerIdentity with the official AWS SDK against the STS regional endpoint the verifier expects (matching s.Host).
- Never rewrite or proxy the presigned URL — re-encoding can duplicate query params or change scheme.
- Always use https; http URLs are rejected by design to prevent plaintext token leakage.
- Keep node region configuration consistent with the kOps cluster region.
When it happens
Trigger: getCallerIdentityV2 (via verifyTokenV2) parses the token's URL successfully but isValidV2 returns false: scheme != https, Host != s.Host, Path != "/", Action query param != GetCallerIdentity, or Action present more than once.
Common situations: Tokens presigned against a different regional STS endpoint than the verifier expects (s.Host mismatch); client built the URL with http instead of https; duplicated Action parameter after URL re-encoding; man-in-the-middle or malicious token; presigning with a tool that appends extra query params.
Related errors
- failed to load default aws config for STS client: %w
- getting AWS STS url: %w
- building AWS STS presigned request: %w
- parsing AWS STS url: %w
- arn %q has unrecognized type
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/55c1d301a14d8f46.
Report an issue: GitHub.