OpenNHP/opennhp · error
could not send https request
Error message
could not send https request: %v
What it means
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.
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
Example fix
// before
client := &http.Client{
Timeout: 120 * time.Minute,
}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("could not send https request: %v", err)
}
// after
client := &http.Client{
Timeout: 120 * time.Minute,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: trustedPool}, // trust the NHP server CA
},
}
var resp *http.Response
var lastErr error
for attempt := 0; attempt < 3; attempt++ {
resp, lastErr = client.Do(req)
if lastErr == nil {
break
}
time.Sleep(time.Duration(attempt+1) * 2 * time.Second) // retry transient network failures
}
if lastErr != nil {
return "", fmt.Errorf("could not send https request: %v", lastErr)
} Defensive patterns
Strategy: retry
Validate before calling
host := device.GetServerPeer().Host()
probeUrl := "http://" + host + "/"
client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Get(probeUrl)
if err != nil {
return fmt.Errorf("NHP server %s unreachable before upload: %v", host, err)
}
resp.Body.Close() Type guard
func serverReachable(host string) bool {
c := &http.Client{Timeout: 10 * time.Second}
resp, err := c.Get("http://" + host + "/")
if err != nil {
return false
}
resp.Body.Close()
return true
} Try / catch
result, err := device.UploadFileToNHPServer(filePath)
if err != nil && strings.Contains(err.Error(), "could not send https request") {
if strings.Contains(err.Error(), "x509") {
// TLS trust problem: install/trust the server CA
} else if errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), "timeout") {
// retry with backoff or increase timeout
}
return fmt.Errorf("network failure uploading to NHP server: %w", err)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- could not read response body
- failed to download ztdo
- could not create request
- unexpected status code
- failed to download HRK
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/061756ba671ddfe2.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/db/utils.go:260
return "", fmt.Errorf("could not close writer: %v", err)
}
uploadUrl := httpHost + "storage/upload"
req, err := http.NewRequest("POST", uploadUrl, body)
if err != nil {
return "", fmt.Errorf("could not create request: %v", err)
}
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{
Timeout: 120 * time.Minute,
}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("could not send https request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
bodyBytes, _ := io.ReadAll(resp.Body)
return "", fmt.Errorf("unexpected status code: %d, content: %s", resp.StatusCode, string(bodyBytes))
}
// read response body
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("could not read response body: %v", err)
}
// parse response body
var respBody ServerResponse
View on GitHub (pinned to 6e04ca5ff0)