juanfont/headscale · warning

dumping config: %w

Error message

dumping config: %w

What it means

Error from the hidden 'headscale dumpConfig' command when viper.WriteConfigAs fails to write the merged configuration to /etc/headscale/config.dump.yaml. This command is integration-test only; failure is almost always filesystem-related (missing directory or no write permission).

Source

Thrown at cmd/headscale/cli/dump_config.go:21

import (
	"fmt"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

func init() {
	rootCmd.AddCommand(dumpConfigCmd)
}

var dumpConfigCmd = &cobra.Command{
	Use:    "dumpConfig",
	Short:  "dump current config to /etc/headscale/config.dump.yaml, integration test only",
	Hidden: true,
	RunE: func(cmd *cobra.Command, args []string) error {
		err := viper.WriteConfigAs("/etc/headscale/config.dump.yaml")
		if err != nil {
			return fmt.Errorf("dumping config: %w", err)
		}

		return nil
	},
}

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Create /etc/headscale and ensure the running user can write to it, or run as the user that owns it
  2. In integration environments, confirm the config volume is mounted writable
  3. If exploring config locally, prefer copying config to a writable path and adjust the command/test instead

Example fix

# before (read-only /etc/headscale)
headscale dumpConfig

# after
sudo mkdir -p /etc/headscale && sudo chown $(id -u) /etc/headscale
headscale dumpConfig
Defensive patterns

Strategy: validation

Validate before calling

if err := os.MkdirAll("/etc/headscale", 0o755); err != nil {
	return err
}
if f, err := os.Create("/etc/headscale/.write_test"); err != nil {
	return fmt.Errorf("no write access to /etc/headscale: %w", err)
} else { f.Close(); os.Remove(f.Name()) }

Try / catch

if err := viper.WriteConfigAs(path); err != nil {
	return fmt.Errorf("dumping config to %s: %w", path, err)
}

Prevention

When it happens

Trigger: Running dumpConfig in an environment where /etc/headscale does not exist or the process lacks write permission to it (non-root user, read-only container filesystem, missing volume mount in the integration container).

Common situations: Integration Docker image where /etc/headscale is mounted read-only or absent; running the hidden command manually on a workstation without root; disk-full conditions in CI.

Related errors


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