juanfont/headscale · error
creating metrics request: %w
Error message
creating metrics request: %w
What it means
Returned by HeadscaleInContainer.SaveMetrics when constructing the HTTP GET request to http://<container-host>:9090/metrics fails. http.NewRequestWithContext only errors on an invalid method or an unparsable URL, so in practice this fires when the container hostname/port produce a malformed URL.
Source
Thrown at integration/hsic/hsic.go:742
err := dockertestutil.WriteLog(t.pool, t.container, &stdout, &stderr)
if err != nil {
return "", "", fmt.Errorf("reading container logs: %w", err)
}
return stdout.String(), stderr.String(), nil
}
// SaveLog saves the current stdout log of the container to a path
// on the host system.
func (t *HeadscaleInContainer) SaveLog(path string) (string, string, error) {
return dockertestutil.SaveLog(t.pool, t.container, path)
}
func (t *HeadscaleInContainer) SaveMetrics(savePath string) error {
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://"+net.JoinHostPort(t.hostname, "9090")+"/metrics", nil)
if err != nil {
return fmt.Errorf("creating metrics request: %w", err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("getting metrics: %w", err)
}
defer resp.Body.Close()
out, err := os.Create(savePath)
if err != nil {
return fmt.Errorf("creating file for metrics: %w", err)
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
return fmt.Errorf("copy response to file: %w", err)
}View on GitHub (pinned to 565fd254d0)
Solutions
- Ensure the headscale container was created and started successfully before calling SaveMetrics (wait for WaitForRunning)
- Check that a custom hsic.WithHostname option, if used, supplies a valid DNS name
- Inspect the wrapped error — url.Error will name the malformed URL part
Defensive patterns
Strategy: validation
Validate before calling
if headscale.GetHostname() == "" {
return errors.New("headscale hostname not set; container not ready for metrics scrape")
} Try / catch
if err := headscale.SaveMetrics(path); err != nil {
t.Logf("metrics not saved: %v", err) // metrics capture is best-effort diagnostics
} Prevention
- Only call SaveMetrics after WaitForRunning succeeds
- Supply a valid hostname when using WithHostname
When it happens
Trigger: Calling SaveMetrics(savePath) when t.hostname is empty or contains characters that make "http://"+net.JoinHostPort(t.hostname, "9090")+"/metrics" an invalid URL.
Common situations: HeadscaleInContainer was constructed without a resolvable hostname; the container failed to start and hostname was never set; a custom option overrode the hostname with an invalid value.
Related errors
- HEADSCALE_CLI_API_KEY environment variable needs to be set
- invalid capability version
- Bad Request: invalid JSON
- creating preauth key with options: %w
- health check timed out
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/3d645f7c6eacaf7a.
Report an issue: GitHub.