{"record":{"id":"d1e546684b044559","repo":"rqlite/rqlite","slug":"error-creating-http-request-w","errorCode":null,"errorMessage":"error creating HTTP request: %w","messagePattern":"error creating HTTP request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cdc/sink.go","lineNumber":81,"sourceCode":"func NewHTTPSink(endpoint string, tlsConfig *tls.Config, timeout time.Duration) *HTTPSink {\n\thttpClient := &http.Client{\n\t\tTransport: &http.Transport{\n\t\t\tTLSClientConfig: tlsConfig,\n\t\t},\n\t\tTimeout: timeout,\n\t}\n\n\treturn &HTTPSink{\n\t\tendpoint:   endpoint,\n\t\thttpClient: httpClient,\n\t}\n}\n\n// Write writes the data to the HTTP endpoint.\nfunc (d *HTTPSink) Write(p []byte) (n int, err error) {\n\treq, err := http.NewRequest(\"POST\", d.endpoint, bytes.NewReader(p))\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"error creating HTTP request: %w\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := d.httpClient.Do(req)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"error sending HTTP request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted {\n\t\treturn 0, fmt.Errorf(\"HTTP request failed with status %d\", resp.StatusCode)\n\t}\n\treturn len(p), nil\n}\n\n// Close releases resources held by the HTTP client.\nfunc (d *HTTPSink) Close() error {\n\tif d.httpClient != nil {","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/rqlite/rqlite/blob/7586a4d1bdbd9a5a80021664c5a863cd850adb60/cdc/sink.go#L63-L99","documentation":"HTTPSink.Write builds a POST request to the webhook endpoint with http.NewRequest before transmitting. If the request cannot be constructed — invalid URL in the endpoint, or malformed payload reader semantics — the error is wrapped as \"error creating HTTP request\". This happens before any network I/O.","triggerScenarios":"The sink's configured endpoint URL is invalid at request-build time (unparseable URL, unsupported scheme like \"ftp://\", or bad host characters) — http.NewRequest returns a *url.Error which is wrapped here.","commonSituations":"CDC config endpoint with typos, spaces, or control characters; environment variable expansion inserting invalid characters; endpoint validated at construction but mutated afterwards.","solutions":["Validate the endpoint with net/url.Parse before configuring the sink: parse errors pinpoint the bad component.","Fix the CDC Endpoint configuration to a well-formed http(s) URL.","Check for stray whitespace/CR-LF in the endpoint value coming from env vars or config files.","Add a startup check that does a dry-run request creation so misconfiguration fails fast."],"exampleFix":"// before\nu, _ := url.Parse(strings.TrimSpace(os.Getenv(\"CDC_ENDPOINT\")))\nsink, _ := NewSink(SinkConfig{Endpoint: \" http://bad url\"})\n// after\nu, err := url.Parse(strings.TrimSpace(os.Getenv(\"CDC_ENDPOINT\")))\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid CDC endpoint %q\", os.Getenv(\"CDC_ENDPOINT\"))\n}\nsink, err := NewSink(SinkConfig{Endpoint: u.String()})","handlingStrategy":"validation","validationCode":"func validURL(raw string) bool {\n    u, err := url.Parse(raw)\n    return err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}","typeGuard":null,"tryCatchPattern":"_, err := http.NewRequest(http.MethodPost, endpoint, bytes.NewReader(payload))\nif err != nil {\n    var uerr *url.Error\n    if errors.As(err, &uerr) {\n        return fmt.Errorf(\"webhook endpoint %q invalid: %v\", endpoint, uerr.Err)\n    }\n    return err\n}","preventionTips":["Validate the endpoint URL (scheme + host) when loading CDC config, before creating the sink.","Strip whitespace/control characters from env-derived endpoint strings.","Log the parsed endpoint at startup so bad values are visible immediately."],"tags":["http","network","cdc","url"],"backgroundTag":"invalid-endpoint-url","analyzedSha":"7586a4d1bdbd9a5a80021664c5a863cd850adb60","analyzedAt":"2026-09-03T07:03:02.260Z","contentChangedAt":"2026-09-03T07:03:02.260Z","schemaVersion":2},"datasetVersion":"2026-09-10T12:17:11.382Z"}