{"record":{"id":"9473bf2fe611e52c","repo":"kubernetes/kops","slug":"parsing-sts-request-url-w","errorCode":null,"errorMessage":"parsing STS request URL: %w","messagePattern":"parsing STS request URL: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/bootstrap/awsbootstrap/verifier.go","lineNumber":399,"sourceCode":"\t}\n\tif u.Path != \"/\" {\n\t\treturn false\n\t}\n\tif u.Query().Get(\"Action\") != \"GetCallerIdentity\" {\n\t\treturn false\n\t}\n\tif len(u.Query()[\"Action\"]) != 1 {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\n// getCallerIdentityV2 will request the presigned token URL, and decode the returned identity.\nfunc (s *stsRequestValidator) getCallerIdentityV2(ctx context.Context, httpClient *http.Client, decoded *awsV2Token) (*GetCallerIdentityResponse, error) {\n\treqURL, err := url.Parse(decoded.URL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing STS request URL: %w\", err)\n\t}\n\n\tif !s.isValidV2(reqURL) {\n\t\treturn nil, fmt.Errorf(\"url not valid for STS request\")\n\t}\n\n\treq := &http.Request{\n\t\tURL:    reqURL,\n\t\tMethod: decoded.Method,\n\t\tHeader: decoded.SignedHeader,\n\t}\n\tresponse, err := httpClient.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"sending STS request: %v\", err)\n\t}\n\tif response != nil {\n\t\tdefer response.Body.Close()\n\t}","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/bootstrap/awsbootstrap/verifier.go#L381-L417","documentation":"The V2 bootstrap token carries a presigned AWS STS GetCallerIdentity URL supplied by the node. The verifier parses that untrusted URL with url.Parse before validating and sending it; if the URL string is malformed and cannot be parsed, the request is rejected with this wrapped error.","triggerScenarios":"verifyTokenV2 decodes an awsV2Token whose URL field fails url.Parse — e.g. the token was truncated, corrupted in transport, or a client constructed the presigned URL incorrectly.","commonSituations":"Token truncated when passed through ConfigMap/secret or CLI flag; node running an AWS SDK version producing a differently-formatted presigned URL than expected; manual tampering or a proxy mangling the token; clock/credential issues causing clients to hand-build URLs.","solutions":["Regenerate the bootstrap token on the node (re-run nodeup / kops bootstrap flow) so a freshly, correctly presigned STS URL is sent.","Confirm nodeup and kOps use compatible AWS SDK versions to produce/consume the presigned URL format.","Check that the token isn't being truncated or mangled in storage/transport (ConfigMap size limits, shell quoting).","Log the failing URL (server-side) to confirm whether it is empty, truncated, or contains invalid characters."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if _, err := url.Parse(token.URL); err != nil {\n  return fmt.Errorf(\"refusing to send bootstrap token: presigned STS URL is not parseable: %w\", err)\n}","typeGuard":"func hasParsableSTSURL(t awsV2Token) bool {\n  u, err := url.Parse(t.URL)\n  return err == nil && u.Scheme != \"\" && u.Host != \"\"\n}","tryCatchPattern":"result, err := verifier.VerifyToken(ctx, token)\nif err != nil && strings.Contains(err.Error(), \"parsing STS request URL\") {\n  // token is corrupt/truncated: regenerate it on the node and retry once\n  token = regenerateBootstrapToken()\n  return verifier.VerifyToken(ctx, token)\n}","preventionTips":["Regenerate tokens with the AWS SDK presigner instead of hand-building URLs.","Avoid truncation in transport: watch ConfigMap size limits and shell quoting when passing tokens.","Keep nodeup and kOps AWS SDK versions aligned so presigned URL formats match."],"tags":["aws","sts","url-parsing","bootstrap"],"backgroundTag":"malformed-url","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}