{"record":{"id":"a6b564000d09eda4","repo":"kubernetes/kops","slug":"parsing-presigned-url-w","errorCode":null,"errorMessage":"parsing presigned url: %w","messagePattern":"parsing presigned url: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/bootstrap/awsbootstrap/verifier.go","lineNumber":485,"sourceCode":"\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}\n\n\tinstance := instances.Reservations[0].Instances[0]\n\n\taddrs = append(addrs, *instance.InstanceId)","sourceCodeStart":467,"sourceCodeEnd":503,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/bootstrap/awsbootstrap/verifier.go#L467-L503","documentation":"This error wraps a failure from Go's net/url.Parse when parsing the URL produced by the AWS STS PresignGetCallerIdentity call in buildSTSRequestValidator. The presigned URL string returned by the AWS SDK could not be parsed into a url.URL, so the verifier cannot extract the Host needed to validate STS requests. This is nearly always a symptom of an AWS SDK misconfiguration (e.g. custom STS endpoint) rather than a logic bug.","triggerScenarios":"NewAWSVerifier calls buildSTSRequestValidator; sts.NewPresignClient(stsClient).PresignGetCallerIdentity returns a signed.URL that url.Parse rejects — e.g. a custom STS endpoint configured via AWS_ENDPOINT_URL_STS or the client config that yields a malformed URL string.","commonSituations":"Developers pointing the SDK at a proxy or local endpoint (LocalStack, custom endpoint resolver) with an invalid or empty URL; corrupted environment variables like AWS_ENDPOINT_URL_STS containing spaces or missing scheme; unusual SDK versions returning unexpected presigned URL formats.","solutions":["Check the STS endpoint configuration (AWS_ENDPOINT_URL_STS, custom resolvers, base URL) and ensure it is a valid absolute http(s) URL","Log signed.URL when the error occurs to see exactly what string fails to parse","Remove any custom endpoint overrides and retry with default AWS endpoints to isolate the cause","Verify AWS SDK versions are consistent (aws-sdk-go-v2) and not mismatched between presign client and config"],"exampleFix":"// before: opaque custom endpoint\nstsClient := sts.NewFromConfig(cfg, func(o *sts.Options) { o.BaseEndpoint = aws.String(os.Getenv(\"STS_URL\")) })\n// after: validate the endpoint before building the client\nep := os.Getenv(\"STS_URL\")\nif ep != \"\" {\n  if _, err := url.Parse(ep); err != nil { return nil, fmt.Errorf(\"invalid STS endpoint %q: %w\", ep, err) }\n}\nstsClient := sts.NewFromConfig(cfg, func(o *sts.Options) { o.BaseEndpoint = aws.String(ep) })","handlingStrategy":"validation","validationCode":"u, err := url.Parse(presignedURL)\nif err != nil || u.Host == \"\" {\n  return fmt.Errorf(\"invalid presigned STS url %q: %w\", presignedURL, err)\n}","typeGuard":"func isValidURL(s string) bool {\n  u, err := url.Parse(s)\n  return err == nil && u.Host != \"\"\n}","tryCatchPattern":"u, err := url.Parse(signed.URL)\nif err != nil {\n  return nil, fmt.Errorf(\"parsing presigned url (raw=%q): %w\", signed.URL, err)\n}","preventionTips":["Avoid custom STS endpoint overrides unless necessary, and validate them at startup","Pin and test AWS SDK versions; presigned URL format is SDK-controlled","Log the raw signed URL on failure for diagnosability"],"tags":["aws","sts","url-parsing","bootstrap"],"backgroundTag":"url-parse-error","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"}