juanfont/headscale · critical
creating headscale container: %w
Error message
creating headscale container: %w
What it means
Returned by Scenario.Headscale when hsic.New fails to build and start the headscale control-server container. It wraps container creation, image pull, config mounting, and container start errors from dockertest.
Source
Thrown at integration/scenario.go:482
// Headscale returns a [ControlServer] instance based on hsic ([hsic.HeadscaleInContainer]).
// If the [Scenario] already has an instance, the pointer to the running container
// will be return, otherwise a new instance will be created.
// TODO(kradalby): make port and headscale configurable, multiple instances support?
func (s *Scenario) Headscale(opts ...hsic.Option) (ControlServer, error) {
s.mu.Lock()
defer s.mu.Unlock()
if headscale, ok := s.controlServers.Load("headscale"); ok {
return headscale, nil
}
if usePostgresForTest {
opts = append(opts, hsic.WithPostgres())
}
headscale, err := hsic.New(s.pool, s.Networks(), opts...)
if err != nil {
return nil, fmt.Errorf("creating headscale container: %w", err)
}
err = headscale.WaitForRunning()
if err != nil {
return nil, fmt.Errorf("reaching headscale container: %w", err)
}
s.controlServers.Store("headscale", headscale)
return headscale, nil
}
// Pool returns the [dockertest.Pool] for the scenario.
func (s *Scenario) Pool() *dockertest.Pool {
return s.pool
}
// GetOrCreateUser gets or creates a user in the [Scenario].View on GitHub (pinned to 565fd254d0)
Solutions
- Build the headscale image first: `make build` followed by the documented docker image build step in integration/README.md
- Run `go run ./cmd/hi doctor` to validate the Docker environment before tests
- Inspect the wrapped error and `docker logs` of the half-created container for startup failures (bad config, bad option)
- Disable/comment custom hsic.Options added by the test to isolate the failing option
Defensive patterns
Strategy: try-catch
Validate before calling
if err := integration.CheckDockerEnvironment(); err != nil { // hi doctor equivalent
t.Skip("docker environment not ready")
} Try / catch
headscale, err := scenario.Headscale()
if err != nil {
// environment-level failure: abort, do not retry blindly
t.Fatalf("control server unavailable: %v", err)
} Prevention
- Build the headscale image before the suite
- Run `hi doctor` first
- Keep test-provided hsic.Options minimal and validated
When it happens
Trigger: First call to s.Headscale() (or any Scenario helper that transitively needs a control server) when the headscale image cannot be pulled/built, config generation fails, or the container exits during startup.
Common situations: Missing or stale locally built headscale image (hsic.New typically uses a locally built image; run make build / the documented docker build first); insufficient Docker resources; a bad hsic.Option (invalid config values, missing env); port conflicts on the host.
Related errors
- reading container logs: %w
- reaching headscale container: %w
- creating tailscale node: %w
- creating certificates for derp test: %w
- %s starting tailscale DERPer container (version: %s): %w
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/00242694f54fb4b3.
Report an issue: GitHub.