{"record":{"id":"cdd6bc8ca29a5cae","repo":"kubernetes/kops","slug":"building-http-request-v","errorCode":null,"errorMessage":"building http request: %v","messagePattern":"building http request: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/bootstrap/awsbootstrap/authenticator.go","lineNumber":189,"sourceCode":"\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"converting token to json: %w\", err)\n\t}\n\n\treturn AWSAuthenticationTokenPrefixV2 + base64.StdEncoding.EncodeToString(token), nil\n}\n\nfunc signV1Request(ctx context.Context, stsURL string, region string, credentials aws.Credentials, signingTime time.Time, kopsRequestBody []byte) (*http.Request, error) {\n\tkopsRequestHash := sha256.Sum256(kopsRequestBody)\n\tkopsRequestHashBase64 := base64.RawStdEncoding.EncodeToString(kopsRequestHash[:])\n\n\t// V1 requests use a well-known body (and host)\n\tbody := []byte(\"Action=GetCallerIdentity&Version=2011-06-15\")\n\n\tbodyHash := sha256.Sum256(body)\n\n\tsignedRequest, err := http.NewRequest(\"POST\", stsURL, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"building http request: %v\", err)\n\t}\n\tsignedRequest.Header.Add(\"Content-Type\", \"application/x-www-form-urlencoded; charset=utf-8\")\n\tsignedRequest.Header.Add(\"X-Kops-Request-Sha\", kopsRequestHashBase64)\n\n\tsigner := v4.NewSigner()\n\n\tservice := \"sts\"\n\n\tif err := signer.SignHTTP(ctx, credentials, signedRequest, hex.EncodeToString(bodyHash[:]), service, region, signingTime); err != nil {\n\t\treturn nil, fmt.Errorf(\"error from SignHTTP: %v\", err)\n\t}\n\n\treturn signedRequest, nil\n}\n","sourceCodeStart":171,"sourceCodeEnd":204,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/bootstrap/awsbootstrap/authenticator.go#L171-L204","documentation":"signV1Request wraps an error from http.NewRequest when constructing the POST request to the STS endpoint with the GetCallerIdentity form body. This fails only if the STS URL is malformed (unparseable) — the body reader is an in-memory bytes.Reader and cannot fail.","triggerScenarios":"http.NewRequest(\"POST\", stsURL, bytes.NewReader(body)) errors inside signV1Request, reached via createTokenV1 from CreateToken or the TestAWSV1Request test: stsURL from getSTSHost is not a valid absolute URL.","commonSituations":"A corrupted STS host (e.g. empty or containing invalid characters) from a bad endpoint override; test harness passing a malformed stsURL directly to signV1Request; proxy/endpoint env tampering.","solutions":["Log/inspect the stsURL passed to signV1Request and validate it parses (url.Parse) and has scheme https.","Fix any AWS_ENDPOINT_URL or BaseEndpoint override producing the bad URL.","In tests, pass a canonical URL like https://sts.us-east-1.amazonaws.com/.","If getSTSHost produced the host, verify the presigned URL parsing upstream (see the 'parsing AWS STS url' error)."],"exampleFix":"// before\nerr := signV1Request(ctx, host, region, creds, time.Now(), body) // host without scheme\n// after\nerr := signV1Request(ctx, \"https://\"+host+\"/\", region, creds, time.Now(), body)","handlingStrategy":"validation","validationCode":"if _, err := url.Parse(stsURL); err != nil || !strings.HasPrefix(stsURL, \"https://\") {\n\treturn fmt.Errorf(\"STS url must be a valid https URL, got %q\", stsURL)\n}","typeGuard":null,"tryCatchPattern":"req, err := signV1Request(ctx, stsURL, region, creds, time.Now(), body)\nif err != nil {\n\treturn fmt.Errorf(\"check STS endpoint URL: %w\", err)\n}","preventionTips":["Ensure the STS host passed to signV1Request includes scheme and trailing slash.","Validate endpoint overrides parse as absolute https URLs.","In tests, use canonical regional STS URLs."],"tags":["http","aws","url-parsing","sigv4"],"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"}