juanfont/headscale · error
DERPer is not ready: %w
Error message
DERPer is not ready: %w
What it means
Returned inside the pool.Retry closure of DERPServerInContainer.WaitForRunning when the HTTPS probe against the DERPer fails at the transport level (connection refused, TLS handshake incomplete, DNS not resolvable). dockertest retries it with backoff; if the DERPer never comes up, this error surfaces.
Source
Thrown at integration/dsic/dsic.go:351
// GetDERPPort returns the DERP port of the DERPer instance.
func (t *DERPServerInContainer) GetDERPPort() int {
return t.derpPort
}
// WaitForRunning blocks until the DERPer instance is ready to be used.
func (t *DERPServerInContainer) WaitForRunning() error {
url := "https://" + net.JoinHostPort(t.GetHostname(), strconv.Itoa(t.GetDERPPort())) + "/"
log.Printf("waiting for DERPer to be ready at %s", url)
insecureTransport := http.DefaultTransport.(*http.Transport).Clone() //nolint
insecureTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint
client := &http.Client{Transport: insecureTransport}
return t.pool.Retry(func() error {
resp, err := client.Get(url) //nolint
if err != nil {
return fmt.Errorf("DERPer is not ready: %w", err)
}
if resp.StatusCode != http.StatusOK {
return errDERPerStatusCodeNotOk
}
return nil
})
}
// ConnectToNetwork connects the DERPer instance to a network.
func (t *DERPServerInContainer) ConnectToNetwork(network *dockertest.Network) error {
return t.container.ConnectToNetwork(network)
}
// WriteFile save file inside the container.
func (t *DERPServerInContainer) WriteFile(path string, data []byte) error {
return integrationutil.WriteFileToContainer(t.pool, t.container, path, data)View on GitHub (pinned to 565fd254d0)
Solutions
- Inspect DERPer container logs to confirm the process started and bound 443
- Verify the container is attached to the expected Docker network and DNS resolution works between containers
- Increase available resources on the CI host or reduce parallelism so startup fits the retry window
Defensive patterns
Strategy: retry
Try / catch
// WaitForRunning already retries; guard only against terminal timeout
if err := derp.WaitForRunning(); err != nil {
log, _ := derp.SaveLog("/tmp/control")
t.Fatalf("derp never became ready; logs at %s: %v", log, err)
} Prevention
- Always capture DERPer logs on readiness failure instead of guessing
- Reserve capacity on CI hosts; overloaded Docker breaks readiness windows
When it happens
Trigger: After starting the DERPer container, probing https://<hostname>:443/ fails repeatedly — server not yet listening, container networking broken, or the DERPer process crashed so the port never opens.
Common situations: DERPer exits due to bad flags or cert problems; Docker network/DNS not propagated so the hostname doesn't resolve; overloaded CI hosts making startup exceed the retry budget.
Related errors
- creating certificates for derp test: %w
- %s starting tailscale DERPer container (version: %s): %w
- writing TLS certificate to container: %w
- writing TLS key to container: %w
- creating or getting network: %w
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/d0e32fc8955b2d3d.
Report an issue: GitHub.