{"record":{"id":"061756ba671ddfe2","repo":"OpenNHP/opennhp","slug":"could-not-send-https-request-v","errorCode":null,"errorMessage":"could not send https request: %v","messagePattern":"could not send https request: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/db/utils.go","lineNumber":260,"sourceCode":"\t\treturn \"\", fmt.Errorf(\"could not close writer: %v\", err)\n\t}\n\n\tuploadUrl := httpHost + \"storage/upload\"\n\n\treq, err := http.NewRequest(\"POST\", uploadUrl, body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"could not create request: %v\", err)\n\t}\n\n\treq.Header.Set(\"Content-Type\", writer.FormDataContentType())\n\n\tclient := &http.Client{\n\t\tTimeout: 120 * time.Minute,\n\t}\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"could not send https request: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tbodyBytes, _ := io.ReadAll(resp.Body)\n\n\t\treturn \"\", fmt.Errorf(\"unexpected status code: %d, content: %s\", resp.StatusCode, string(bodyBytes))\n\t}\n\n\t// read response body\n\tbodyBytes, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"could not read response body: %v\", err)\n\t}\n\n\t// parse response body\n\tvar respBody ServerResponse\n","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/db/utils.go#L242-L278","documentation":"The function sends the prepared POST with client.Do(req) using an http.Client with a 120-minute timeout. Any transport-level failure — DNS resolution, TCP connect, TLS handshake, connection reset, or timeout — is wrapped as \"could not send https request: %v\" with the Go net/http error verbatim. This is a client-side network failure, not an HTTP error status.","triggerScenarios":"client.Do fails in UploadFileToNHPServer (endpoints/db/utils.go:258-261): server unreachable (connection refused), DNS failure for the configured host, TLS certificate errors when the https fallback (utils.go:201) is used against a server with a self-signed/untrusted cert, request taking longer than the 120s… er, 120-minute client.Timeout, or network interruption mid-upload of a large body.","commonSituations":"NHP-DB server down or wrong port in the peer configuration; firewall blocking the HTTP(S) port; https fallback against a demo server with a self-signed certificate yielding \"x509: certificate signed by unknown authority\"; uploading huge files over a flaky VPN link; DNS not resolving the server hostname.","solutions":["Read the wrapped error: \"connection refused\" → check the server process and port; \"no such host\" → fix DNS; \"x509\" → fix or trust the server certificate (or configure TLS properly rather than disabling verification)","Verify the NHP-DB server's HTTP endpoint is up and reachable: curl the httpHost probe URL used at utils.go:195 from the same machine","Correct the server Host in the peer configuration (host/IP and port) so the probe and upload URLs point at the right listener","If uploads are large and links are slow, confirm the 120-minute timeout is sufficient or raise it; for transient network errors, add bounded retry with backoff around the upload"],"exampleFix":"// before\nclient := &http.Client{\n\tTimeout: 120 * time.Minute,\n}\nresp, err := client.Do(req)\nif err != nil {\n\treturn \"\", fmt.Errorf(\"could not send https request: %v\", err)\n}\n// after\nclient := &http.Client{\n\tTimeout: 120 * time.Minute,\n\tTransport: &http.Transport{\n\t\tTLSClientConfig: &tls.Config{RootCAs: trustedPool}, // trust the NHP server CA\n\t},\n}\nvar resp *http.Response\nvar lastErr error\nfor attempt := 0; attempt < 3; attempt++ {\n\tresp, lastErr = client.Do(req)\n\tif lastErr == nil {\n\t\tbreak\n\t}\n\ttime.Sleep(time.Duration(attempt+1) * 2 * time.Second) // retry transient network failures\n}\nif lastErr != nil {\n\treturn \"\", fmt.Errorf(\"could not send https request: %v\", lastErr)\n}","handlingStrategy":"retry","validationCode":"host := device.GetServerPeer().Host()\nprobeUrl := \"http://\" + host + \"/\"\nclient := &http.Client{Timeout: 10 * time.Second}\nresp, err := client.Get(probeUrl)\nif err != nil {\n\treturn fmt.Errorf(\"NHP server %s unreachable before upload: %v\", host, err)\n}\nresp.Body.Close()","typeGuard":"func serverReachable(host string) bool {\n\tc := &http.Client{Timeout: 10 * time.Second}\n\tresp, err := c.Get(\"http://\" + host + \"/\")\n\tif err != nil {\n\t\treturn false\n\t}\n\tresp.Body.Close()\n\treturn true\n}","tryCatchPattern":"result, err := device.UploadFileToNHPServer(filePath)\nif err != nil && strings.Contains(err.Error(), \"could not send https request\") {\n\tif strings.Contains(err.Error(), \"x509\") {\n\t\t// TLS trust problem: install/trust the server CA\n\t} else if errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), \"timeout\") {\n\t\t// retry with backoff or increase timeout\n\t}\n\treturn fmt.Errorf(\"network failure uploading to NHP server: %w\", err)\n}","preventionTips":["Health-check the server endpoint before large uploads","Ensure the server's TLS certificate is trusted by the client (add CA to system pool) when the https fallback kicks in","Set firewall/security-group rules to allow the HTTP(S) port between agent/db and server","Use bounded retry with exponential backoff for transient network errors","Keep the 120-minute client timeout aligned with your largest file over the slowest link"],"tags":["go","network","http","tls","timeout"],"backgroundTag":"network-request-failed","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}