juanfont/headscale · critical
reaching headscale container: %w
Error message
reaching headscale container: %w
What it means
Returned by Scenario.Headscale when the freshly created headscale container starts but never becomes reachable — headscale.WaitForRunning() polls the server's health/ready endpoint and timed out. It means the container exists but headscale inside it is not serving.
Source
Thrown at integration/scenario.go:487
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].
func (s *Scenario) GetOrCreateUser(userStr string) *User {
s.mu.Lock()
defer s.mu.Unlock()
if user, ok := s.users[userStr]; ok {View on GitHub (pinned to 565fd254d0)
Solutions
- Dump the container logs right after failure: `docker logs <headscale-container>` — headscale usually logs the fatal config error
- If using WithPostgres, verify the database container became healthy before headscale starts
- Regenerate certs/keys if the test mounts stale or mismatched TLS material
- On slow machines, retry the run once — but if it repeats, treat it as a config/code defect per the repo's flake policy
Defensive patterns
Strategy: retry
Try / catch
headscale, err := scenario.Headscale()
if err != nil {
// pull container logs immediately — WaitForRunning failures are almost always
// a startup crash visible in stderr
t.Fatalf("headscale not ready: %v — check container logs", err)
} Prevention
- Always dump control-container logs on readiness timeout
- Validate mounted config (certs, keys, DB settings) before the run
- Pre-warm dependencies (e.g. Postgres) before headscale starts
When it happens
Trigger: Calling any Scenario helper that triggers s.Headscale() when the headscale process inside the container crashes on startup, listens on a different address, or the health check cannot reach the port (network attachment issues).
Common situations: Broken headscale config mounted into the container (bad TLS certs, invalid noise key, unreachable DB); headscale binary/image version mismatch where the config keys changed; Postgres option enabled but the DB container is not ready; slow CI machine hitting the readiness timeout.
Related errors
- creating headscale container: %w
- STUN address not set
- initial DERPMap is empty, Headscale requires at least one en
- database type not supported
- unsupported policy mode
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/bfa02c90784bf564.
Report an issue: GitHub.