kubernetes/kops · error
building presigned request: %w
Error message
building presigned request: %w
What it means
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.
Source
Thrown at pkg/bootstrap/awsbootstrap/verifier.go:481
if response.StatusCode != 200 {
return nil, fmt.Errorf("received status code %d from STS: %s", response.StatusCode, string(responseBody))
}
callerIdentity := &GetCallerIdentityResponse{}
err = xml.NewDecoder(bytes.NewReader(responseBody)).Decode(callerIdentity)
if err != nil {
return nil, fmt.Errorf("decoding STS response: %v", err)
}
return callerIdentity, nil
}
// buildSTSRequestValidator determines the form of a valid STS presigned URL.
func buildSTSRequestValidator(ctx context.Context, stsClient *sts.Client) (*stsRequestValidator, error) {
// We build a presigned token ourselves, primarily to get the expected hostname for the endpoint.
signed, err := sts.NewPresignClient(stsClient).PresignGetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
if err != nil {
return nil, fmt.Errorf("building presigned request: %w", err)
}
u, err := url.Parse(signed.URL)
if err != nil {
return nil, fmt.Errorf("parsing presigned url: %w", err)
}
return &stsRequestValidator{Host: u.Host}, nil
}
// GetInstanceCertificateNames returns the instance names and addresses that should go into
// certificates: the instance ID, the private DNS name and the IP addresses.
func GetInstanceCertificateNames(instances *ec2.DescribeInstancesOutput) (addrs []string, err error) {
if len(instances.Reservations) != 1 {
return nil, fmt.Errorf("too many reservations returned for the single instance-id")
}
if len(instances.Reservations[0].Instances) != 1 {
return nil, fmt.Errorf("too many instances returned for the single instance-id")
}View on GitHub (pinned to 4c8573c808)
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.
Example fix
// before: STS client built with no region, presign fails
stsClient := sts.NewFromConfig(aws.Config{})
verifier, err := NewAWSVerifier(ctx, stsClient, ...)
// after: explicit region so presigning can resolve the endpoint
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-east-1"))
if err != nil { return err }
stsClient := sts.NewFromConfig(cfg)
verifier, err := NewAWSVerifier(ctx, stsClient, ...) Defensive patterns
Strategy: validation
Validate before calling
// Validate region + credential presence before constructing the verifier
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
return fmt.Errorf("aws config unavailable: %w", err)
}
if cfg.Region == "" {
return errors.New("AWS region not set: set AWS_REGION or pass config.WithRegion(...)")
}
creds, err := cfg.Credentials.Retrieve(ctx)
if err != nil || !creds.HasKeys() {
return errors.New("AWS credentials not found: set env vars, shared credentials file, or IAM role")
}
stsClient := sts.NewFromConfig(cfg) Type guard
func isPresignConfigError(err error) bool {
if err == nil { return false }
msg := err.Error()
return strings.Contains(msg, "building presigned request") &&
(strings.Contains(msg, "no credential") || strings.Contains(msg, "region") || strings.Contains(msg, "endpoint"))
} Try / catch
verifier, err := NewAWSVerifier(ctx, stsClient, ...)
if err != nil {
if isPresignConfigError(err) {
return fmt.Errorf("verifier setup needs valid AWS region and credentials: %w", err)
}
return err
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- error initializing AWS client: %v
- building AWS STS presigned request: %w
- error getting AWS account ID: %v
- failed to load AWS config: %w
- DeviceName not set for volume
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/85f7ab1b4a6c500c.
Report an issue: GitHub.