{"record":{"id":"85f7ab1b4a6c500c","repo":"kubernetes/kops","slug":"building-presigned-request-w","errorCode":null,"errorMessage":"building presigned request: %w","messagePattern":"building presigned request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/bootstrap/awsbootstrap/verifier.go","lineNumber":481,"sourceCode":"\tif response.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"received status code %d from STS: %s\", response.StatusCode, string(responseBody))\n\t}\n\n\tcallerIdentity := &GetCallerIdentityResponse{}\n\terr = xml.NewDecoder(bytes.NewReader(responseBody)).Decode(callerIdentity)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"decoding STS response: %v\", err)\n\t}\n\n\treturn callerIdentity, nil\n}\n\n// buildSTSRequestValidator determines the form of a valid STS presigned URL.\nfunc buildSTSRequestValidator(ctx context.Context, stsClient *sts.Client) (*stsRequestValidator, error) {\n\t// We build a presigned token ourselves, primarily to get the expected hostname for the endpoint.\n\tsigned, err := sts.NewPresignClient(stsClient).PresignGetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"building presigned request: %w\", err)\n\t}\n\tu, err := url.Parse(signed.URL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing presigned url: %w\", err)\n\t}\n\treturn &stsRequestValidator{Host: u.Host}, nil\n}\n\n// GetInstanceCertificateNames returns the instance names and addresses that should go into\n// certificates: the instance ID, the private DNS name and the IP addresses.\nfunc GetInstanceCertificateNames(instances *ec2.DescribeInstancesOutput) (addrs []string, err error) {\n\tif len(instances.Reservations) != 1 {\n\t\treturn nil, fmt.Errorf(\"too many reservations returned for the single instance-id\")\n\t}\n\n\tif len(instances.Reservations[0].Instances) != 1 {\n\t\treturn nil, fmt.Errorf(\"too many instances returned for the single instance-id\")\n\t}","sourceCodeStart":463,"sourceCodeEnd":499,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/bootstrap/awsbootstrap/verifier.go#L463-L499","documentation":"buildSTSRequestValidator constructs a reference presigned GetCallerIdentity URL using the AWS SDK's PresignClient, primarily to learn the expected STS hostname for later token validation. The 'building presigned request: %w' error means PresignGetCallerIdentity failed — typically because the STS client has no usable credentials to sign with, its region/endpoint configuration is invalid, or the SDK could not resolve the endpoint.","triggerScenarios":"Called from NewAWSVerifier (verifier construction) and tests when sts.NewPresignClient(stsClient).PresignGetCallerIdentity returns an error: missing/empty AWS credentials in the signing chain, no region set on the STS client config, invalid region name, or credential-provider errors (e.g. expired static keys, unreadable credential files).","commonSituations":"Environment lacks AWS_REGION/AWS_DEFAULT_REGION where no region can be inferred (e.g. running kOps control plane off-cluster); shared credentials file or env vars absent/misnamed; expired AWS_SESSION_TOKEN with static keys; typo'd region causing endpoint resolution failure; test fixtures constructing a verifier without valid-looking credentials.","solutions":["Export AWS_REGION (or AWS_DEFAULT_REGION) so the STS client resolves an endpoint; outside AWS use e.g. us-east-1 or your cluster's region.","Provide signing credentials via env (AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY), the shared credentials file, or an attached IAM role — presigning requires some credential even though the URL is presigned.","Run aws sts get-caller-identity with the same environment to confirm credentials and region resolve.","Check for expired session credentials and refresh them (aws sso login, new assume-role, or updated credential file).","Verify the region string is valid and supported; an invalid region breaks endpoint resolution in the SDK."],"exampleFix":"// before: STS client built with no region, presign fails\nstsClient := sts.NewFromConfig(aws.Config{})\nverifier, err := NewAWSVerifier(ctx, stsClient, ...)\n// after: explicit region so presigning can resolve the endpoint\ncfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(\"us-east-1\"))\nif err != nil { return err }\nstsClient := sts.NewFromConfig(cfg)\nverifier, err := NewAWSVerifier(ctx, stsClient, ...)","handlingStrategy":"validation","validationCode":"// Validate region + credential presence before constructing the verifier\ncfg, err := config.LoadDefaultConfig(ctx)\nif err != nil {\n    return fmt.Errorf(\"aws config unavailable: %w\", err)\n}\nif cfg.Region == \"\" {\n    return errors.New(\"AWS region not set: set AWS_REGION or pass config.WithRegion(...)\")\n}\ncreds, err := cfg.Credentials.Retrieve(ctx)\nif err != nil || !creds.HasKeys() {\n    return errors.New(\"AWS credentials not found: set env vars, shared credentials file, or IAM role\")\n}\nstsClient := sts.NewFromConfig(cfg)","typeGuard":"func isPresignConfigError(err error) bool {\n    if err == nil { return false }\n    msg := err.Error()\n    return strings.Contains(msg, \"building presigned request\") &&\n        (strings.Contains(msg, \"no credential\") || strings.Contains(msg, \"region\") || strings.Contains(msg, \"endpoint\"))\n}","tryCatchPattern":"verifier, err := NewAWSVerifier(ctx, stsClient, ...)\nif err != nil {\n    if isPresignConfigError(err) {\n        return fmt.Errorf(\"verifier setup needs valid AWS region and credentials: %w\", err)\n    }\n    return err\n}","preventionTips":["Always set AWS_REGION explicitly when running the verifier outside an EC2 instance metadata context.","Confirm credentials resolve with `aws sts get-caller-identity` in the same environment before starting the controller.","Refresh expiring session credentials (SSO/assume-role) before long-running verifier processes.","Use config.LoadDefaultConfig so region/credential sources follow the standard SDK chain.","Catch this at verifier construction time (fail fast) rather than at first token verification."],"tags":["aws","sts","presign","credentials","configuration"],"backgroundTag":"sts-presign-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}