juanfont/headscale · warning

creating request: %w

Error message

creating request: %w

What it means

"creating request: %w" at cmd/dev/main.go:252 wraps http.NewRequestWithContext inside waitForHealth's poll loop. NewRequestWithContext only fails on an invalid method or an unparseable URL, so in cmd/dev the practical cause is the health URL being malformed, or — most commonly — ctx already cancelled so the error surfaced at request construction. The URL is built as http://127.0.0.1:%d/health from the -port flag.

Source

Thrown at cmd/dev/main.go:252

		return fmt.Errorf("headscale exited: %w", err)
	}

	return nil
}

// waitForHealth polls the health endpoint until it returns 200 or the
// timeout expires.
func waitForHealth(ctx context.Context, url string, timeout time.Duration) error {
	deadline := time.Now().Add(timeout)

	for time.Now().Before(deadline) {
		if ctx.Err() != nil {
			return ctx.Err()
		}

		req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
		if err != nil {
			return fmt.Errorf("creating request: %w", err)
		}

		resp, err := http.DefaultClient.Do(req)
		if err == nil {
			resp.Body.Close()

			if resp.StatusCode == http.StatusOK {
				return nil
			}
		}

		// Busy-wait is acceptable for a dev tool polling a local server.
		time.Sleep(200 * time.Millisecond) //nolint:forbidigo
	}

	return errHealthTimeout
}

View on GitHub (pinned to 565fd254d0)

Solutions

  1. If you pressed Ctrl+C, this is benign shutdown noise — no action needed
  2. Otherwise pass a sane port: `go run ./cmd/dev -port 8080` and confirm http://127.0.0.1:8080/health is the intended URL
Defensive patterns

Strategy: retry

Validate before calling

// sanity-check the health URL once before the poll loop
if _, err := url.ParseRequestURI(fmt.Sprintf("http://127.0.0.1:%d/health", port)); err != nil {
	return fmt.Errorf("invalid health URL for port %d", port)
}

Try / catch

req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
	if ctx.Err() != nil {
		return ctx.Err() // benign shutdown, stop polling
	}
	return fmt.Errorf("creating request: %w", err)
}

Prevention

When it happens

Trigger: Passing a -port value that renders the URL invalid (negative, or overflowing into a bad string after formatting); Ctrl+C (SIGINT/SIGTERM) cancelling the signal.NotifyContext between the loop's ctx.Err() check and request construction, surfacing context.Canceled through this wrap.

Common situations: Interrupting cmd/dev during startup; exotic port values from scripts computing -port dynamically.

Related errors


AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15). Data as JSON: /api/errors/591fbf088ef0f7c4. Report an issue: GitHub.