juanfont/headscale · error

writing %q: %w

Error message

writing %q: %w

What it means

Generic per-file error when an option-registered extra file (hsic.filesInContainer, e.g. WithConfigFile/WithFile style options) cannot be written into the container. The %q names the exact path, distinguishing it from the config/TLS/policy writes.

Source

Thrown at integration/hsic/hsic.go:627

		}
	}

	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)
		}
	}

	return hsic, nil
}

func (t *HeadscaleInContainer) ConnectToNetwork(network *dockertest.Network) error {
	return t.container.ConnectToNetwork(network)
}

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Look at the %q path in the message and verify its parent directory exists in the container image
  2. Check the container is running (docker ps) and its logs
  3. Fix the path in the test option to an absolute path that exists in the image
  4. Re-run to rule out transient exec failures

Example fix

// before
hsic.WithFile("derp.yaml", contents), // path may lack a parent dir
// after (verify actual option signature; use absolute path)
hsic.WithFile("/etc/headscale/derp.yaml", contents),
Defensive patterns

Strategy: validation

Validate before calling

// Before adding a file, ensure the parent dir exists in the image
for _, f := range files {
    if !strings.HasPrefix(f.path, "/") { return fmt.Errorf("file path %q must be absolute", f.path) }
}

Prevention

When it happens

Trigger: Any test option that adds filesInContainer entries (custom DERP config, extra certs, test fixtures) where WriteFile(path, contents) fails: container not writable, path invalid (missing parent dir), or contents empty where the copy needs input.

Common situations: Custom file path pointing to a directory that does not exist in the image; container crashed mid-setup; typo'd absolute path in the option.

Related errors


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