kubernetes/kops · error

building (v1) signed request: %w

Error message

building (v1) signed request: %w

What it means

createTokenV1 wraps a failure from signV1Request, which constructs an http.Request and signs it with AWS SigV4 (v4.NewSigner().SignHTTP) to produce the presigned GetCallerIdentity call. If request construction or signing fails, the v1 bootstrap token cannot be built.

Source

Thrown at pkg/bootstrap/awsbootstrap/authenticator.go:127

	return a.createTokenV2(ctx, body)
}

func (a *awsAuthenticator) createTokenV1(ctx context.Context, body []byte) (string, error) {
	credentials, err := a.credentialsProvider.Retrieve(ctx)
	if err != nil {
		return "", fmt.Errorf("getting AWS credentials: %w", err)
	}

	host, err := a.getSTSHost(ctx)
	if err != nil {
		return "", fmt.Errorf("getting AWS STS url: %w", err)
	}
	stsURL := "https://" + host + "/"
	region := a.region

	req, err := signV1Request(ctx, stsURL, region, credentials, time.Now(), body)
	if err != nil {
		return "", fmt.Errorf("building (v1) signed request: %w", err)
	}
	headers, err := json.Marshal(req.Header)
	if err != nil {
		return "", fmt.Errorf("converting headers to json: %w", err)
	}
	return AWSAuthenticationTokenPrefixV1 + base64.StdEncoding.EncodeToString(headers), nil
}

func (a *awsAuthenticator) getSTSHost(ctx context.Context) (string, error) {
	// An inefficient but reliable way to get the STS url
	presignClient := sts.NewPresignClient(a.sts)
	stsRequest, err := presignClient.PresignGetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
	if err != nil {
		return "", fmt.Errorf("building AWS STS presigned request: %w", err)
	}
	u, err := url.Parse(stsRequest.URL)
	if err != nil {
		return "", fmt.Errorf("parsing AWS STS url: %w", err)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the region value passed to the authenticator is a valid AWS region string (non-empty, e.g. us-east-1).
  2. Verify the retrieved credentials are non-empty (AccessKeyID/SecretAccessKey) before calling CreateToken.
  3. Ensure the aws-sdk-go-v2 v4 signer package version matches the rest of the SDK modules in go.mod (run `make gomod`).
  4. Re-run with verbose logging to see the underlying wrapped error from SignHTTP.

Example fix

// before
auth, _ := awsbootstrap.NewAuthenticator(ctx, "", stsClient, creds) // empty region
// after
auth, _ := awsbootstrap.NewAuthenticator(ctx, "us-east-1", stsClient, creds)
Defensive patterns

Strategy: try-catch

Validate before calling

creds, err := credProvider.Retrieve(ctx)
if err == nil && (creds.AccessKeyID == "" || creds.SecretAccessKey == "") {
	return fmt.Errorf("incomplete AWS credentials")
}

Try / catch

token, err := auth.CreateToken(body)
if err != nil {
	if strings.Contains(err.Error(), "building (v1) signed request") {
		// inspect region + credentials, then retry after fixing config
	}
}

Prevention

When it happens

Trigger: signV1Request(ctx, stsURL, region, credentials, time.Now(), body) returns an error during CreateToken (v1 path): bad STS URL, malformed credentials (empty access key), or an internal SigV4 signer failure.

Common situations: Empty region string causing SigV4 credential-scope errors; credentials retrieved with empty AccessKeyID; unit/integration tests stubbing the signer incorrectly; go aws-sdk-go-v2/features/ec2/imds or signer version incompatibilities after dependency upgrades.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/e064ccb58db074e5. Report an issue: GitHub.