{"record":{"id":"0a907a5e66d18661","repo":"kubernetes/kops","slug":"parsing-aws-sts-url-w","errorCode":null,"errorMessage":"parsing AWS STS url: %w","messagePattern":"parsing AWS STS url: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/bootstrap/awsbootstrap/authenticator.go","lineNumber":145,"sourceCode":"\t\treturn \"\", fmt.Errorf(\"building (v1) signed request: %w\", err)\n\t}\n\theaders, err := json.Marshal(req.Header)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"converting headers to json: %w\", err)\n\t}\n\treturn AWSAuthenticationTokenPrefixV1 + base64.StdEncoding.EncodeToString(headers), nil\n}\n\nfunc (a *awsAuthenticator) getSTSHost(ctx context.Context) (string, error) {\n\t// An inefficient but reliable way to get the STS url\n\tpresignClient := sts.NewPresignClient(a.sts)\n\tstsRequest, err := presignClient.PresignGetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"building AWS STS presigned request: %w\", err)\n\t}\n\tu, err := url.Parse(stsRequest.URL)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"parsing AWS STS url: %w\", err)\n\t}\n\treturn u.Host, err\n}\n\nfunc (a *awsAuthenticator) createTokenV2(ctx context.Context, body []byte) (string, error) {\n\tsha := sha256.Sum256(body)\n\n\tpresignClient := sts.NewPresignClient(a.sts)\n\n\t// Ensure the signature is only valid for this particular body content.\n\tstsRequest, err := presignClient.PresignGetCallerIdentity(ctx, &sts.GetCallerIdentityInput{}, func(po *sts.PresignOptions) {\n\t\tpo.ClientOptions = append(po.ClientOptions, func(o *sts.Options) {\n\t\t\to.APIOptions = append(o.APIOptions, smithyhttp.AddHeaderValue(\"X-Kops-Request-SHA\", base64.RawStdEncoding.EncodeToString(sha[:])))\n\t\t})\n\t})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"building AWS STS presigned request: %w\", err)\n\t}","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/bootstrap/awsbootstrap/authenticator.go#L127-L163","documentation":"getSTSHost wraps a failure from url.Parse(stsRequest.URL) after a successful presign. The presigned URL string could not be parsed as a URL, so the STS hostname cannot be extracted. This is nearly impossible with SDK-generated URLs and indicates a corrupted or overridden endpoint value.","triggerScenarios":"url.Parse fails inside getSTSHost (called by createTokenV1 via CreateToken) — only if stsRequest.URL contains invalid characters, typically from a misconfigured custom STS BaseEndpoint containing spaces/invalid characters.","commonSituations":"Custom STS endpoint set via AWS_ENDPOINT_URL or sts client BaseEndpoint with a typo (e.g. missing scheme or embedded whitespace); proxy env vars injecting garbage into endpoint resolution in unusual test setups.","solutions":["Check AWS_ENDPOINT_URL / AWS_ENDPOINT_URL_STS and any BaseEndpoint override — fix typos and ensure a valid https:// URL.","Remove the custom endpoint and retest against the default regional STS endpoint.","If using a local mock (localstack etc.), ensure the endpoint URL is well-formed, e.g. https://sts.local:4566."],"exampleFix":"// before\nAWS_ENDPOINT_URL=\"sts amazonaws com\"  // invalid\n// after\nAWS_ENDPOINT_URL=\"https://sts.us-east-1.amazonaws.com\"","handlingStrategy":"validation","validationCode":"if ep := os.Getenv(\"AWS_ENDPOINT_URL_STS\"); ep != \"\" {\n\tif _, err := url.Parse(ep); err != nil || !strings.HasPrefix(ep, \"https://\") {\n\t\treturn fmt.Errorf(\"invalid AWS_ENDPOINT_URL_STS: %q\", ep)\n\t}\n}","typeGuard":null,"tryCatchPattern":"host, err := a.getSTSHost(ctx)\nif err != nil {\n\treturn fmt.Errorf(\"check AWS_ENDPOINT_URL / BaseEndpoint config: %w\", err)\n}","preventionTips":["Always use fully-qualified https:// endpoint URLs in overrides.","Lint endpoint env vars in CI before bootstrap jobs.","Prefer the default regional endpoint unless testing locally."],"tags":["aws","sts","url-parsing","endpoint"],"backgroundTag":"invalid-endpoint-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"}