juanfont/headscale · error

writing TLS key to container: %w

Error message

writing TLS key to container: %w

What it means

Companion to 676: writing the TLS private key to tlsKeyPath failed. Same mechanism (docker file write into the container), same failure modes; only the artifact (key PEM) differs.

Source

Thrown at integration/hsic/hsic.go:620

		return nil, fmt.Errorf("writing headscale config to container: %w", err)
	}

	if hsic.aclPolicy != nil {
		err = hsic.writePolicy(hsic.aclPolicy)
		if err != nil {
			return nil, fmt.Errorf("writing policy: %w", err)
		}
	}

	if hsic.hasTLS() {
		err = hsic.WriteFile(tlsCertPath, hsic.tlsCert)
		if err != nil {
			return nil, fmt.Errorf("writing TLS certificate to container: %w", err)
		}

		err = hsic.WriteFile(tlsKeyPath, hsic.tlsKey)
		if err != nil {
			return nil, fmt.Errorf("writing TLS key to container: %w", err)
		}
	}

	for _, f := range hsic.filesInContainer {
		err := hsic.WriteFile(f.path, f.contents)
		if err != nil {
			return nil, fmt.Errorf("writing %q: %w", f.path, err)
		}
	}

	// Load the database from policy file on repeat until it succeeds,
	// this is done as the container sleeps before starting headscale.
	if hsic.aclPolicy != nil && hsic.policyMode == types.PolicyModeDB {
		err := pool.Retry(hsic.reloadDatabasePolicy)
		if err != nil {
			return nil, fmt.Errorf("loading database policy on startup: %w", err)
		}
	}

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Check container status and logs — it died between cert and key write
  2. Free Docker resources (memory/CPU pressure causes mid-setup container deaths)
  3. Verify tlsKeyPath exists/writable in the image
  4. Re-run the scenario after cleanup
Defensive patterns

Strategy: validation

Validate before calling

if !pemValid(hsic.tlsKey) { return nil, fmt.Errorf("tls key not valid PEM") }

Type guard

func pemPrivateKey(b []byte) bool {
    blk, _ := pem.Decode(b)
    return blk != nil && strings.Contains(blk.Type, "PRIVATE KEY")
}

Prevention

When it happens

Trigger: hasTLS() true and hsic.WriteFile(tlsKeyPath, hsic.tlsKey) fails after the cert write succeeded — partial TLS setup: cert written, key not, leaving the container misconfigured if the error were ignored (it is not; construction aborts).

Common situations: Container dying between the two writes under memory pressure; transient exec failure; custom image lacking the key path.

Understand the failure class

Related errors


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