{"record":{"id":"20466f8e0ff16691","repo":"grpc/grpc-go","slug":"failed-to-create-http-request-v","errorCode":null,"errorMessage":"failed to create http request: %v","messagePattern":"failed to create http request: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/sts/sts.go","lineNumber":291,"sourceCode":"\t\tRequestedTokenType: opts.RequestedTokenType,\n\t\tSubjectToken:       string(subToken),\n\t\tSubjectTokenType:   opts.SubjectTokenType,\n\t}\n\tif opts.ActorTokenPath != \"\" {\n\t\tactorToken, err := readActorTokenFrom(opts.ActorTokenPath)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treqParams.ActorToken = string(actorToken)\n\t\treqParams.ActorTokenType = opts.ActorTokenType\n\t}\n\tjsonBody, err := json.Marshal(reqParams)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq, err := http.NewRequestWithContext(ctx, \"POST\", opts.TokenExchangeServiceURI, bytes.NewBuffer(jsonBody))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create http request: %v\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treturn req, nil\n}\n\nfunc sendRequest(client httpDoer, req *http.Request) ([]byte, error) {\n\t// http.Client returns a non-nil error only if it encounters an error\n\t// caused by client policy (such as CheckRedirect), or failure to speak\n\t// HTTP (such as a network connectivity problem). A non-2xx status code\n\t// doesn't cause an error.\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// When the http.Client returns a non-nil error, it is the\n\t// responsibility of the caller to read the response body till an EOF is\n\t// encountered and to close it.","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/sts/sts.go#L273-L309","documentation":"Returned by constructRequest in sts/sts.go:291 when http.NewRequestWithContext fails while building the POST to the token-exchange endpoint. NewRequestWithContext fails on a malformed URL (e.g. control characters, bad escaping) or on a nil/invalid context. The wrapped %v is the underlying error.","triggerScenarios":"TokenExchangeServiceURI parses (passes validateOptions) but is structurally invalid for http.NewRequest; the passed context is nil; the URI contains characters the URL parser in NewRequest rejects.","commonSituations":"A URI that passed url.Parse but trips net/http's stricter validation; a context that was already canceled and somehow nil-wrapped; copy-paste of a URL with embedded credentials or whitespace.","solutions":["Sanitize and re-validate TokenExchangeServiceURI with url.ParseRequestURI before calling NewCredentials.","Ensure the context passed into the RPC (and thus GetRequestMetadata) is non-nil and not pre-canceled.","Strip whitespace/control characters from the configured URI."],"exampleFix":"// before\nopts := sts.Options{TokenExchangeServiceURI: strings.TrimSpace(rawURI) + \"\\r\\n\", ...}\n\n// after\nu, err := url.ParseRequestURI(strings.TrimSpace(rawURI))\nif err != nil { return err }\nopts := sts.Options{TokenExchangeServiceURI: u.String(), ...}","handlingStrategy":"validation","validationCode":"u, err := url.ParseRequestURI(strings.TrimSpace(opts.TokenExchangeServiceURI))\nif err != nil { return fmt.Errorf(\"invalid STS request URI: %w\", err) }\nopts.TokenExchangeServiceURI = u.String()\n// also ensure the RPC context passed in is non-nil and not pre-canceled\nstsCreds, err := sts.NewCredentials(opts)","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"failed to create http request\") {\n    // URI malformed for net/http; sanitize or the context was nil/canceled\n}","preventionTips":["Sanitize the STS URI (trim whitespace/control chars) at config load.","Validate with url.ParseRequestURI, which is stricter than url.Parse.","Never pass a nil context to RPCs that use STS per-RPC creds."],"tags":["sts","network","http","validation","go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}