cloudflare/cloudflared · error

rc-update add %s default: %w

Error message

rc-update add %s default: %w

What it means

This error wraps a failure from `rc-update add cloudflared default` while installing the cloudflared OpenRC service on Gentoo/Alpine-style systems. The rc-update command registers the service script (typically /etc/init.d/cloudflared) into the default runlevel so it starts at boot. cloudflared throws it whenever the rc-update binary exits non-zero, and it wraps the underlying exec error so the root cause (missing binary, permission failure, missing init script) is preserved.

Source

Thrown at cmd/cloudflared/linux_service.go:434

	return runCommand("service", "cloudflared", "start")
}

func installOpenRC(templateArgs *ServiceTemplateArgs, autoUpdate bool) error {
	if autoUpdate {
		templateArgs.ExtraArgs = append([]string{"--autoupdate-freq", "24h0m0s"}, templateArgs.ExtraArgs...)
	} else {
		templateArgs.ExtraArgs = append([]string{"--no-autoupdate"}, templateArgs.ExtraArgs...)
	}

	if err := openrcConfTemplate.Generate(templateArgs); err != nil {
		return fmt.Errorf("error generating OpenRC conf.d template: %w", err)
	}
	if err := openrcTemplate.Generate(templateArgs); err != nil {
		return fmt.Errorf("error generating OpenRC service template: %w", err)
	}

	if err := runCommand("rc-update", "add", cloudflaredOpenRCService, "default"); err != nil {
		return fmt.Errorf("rc-update add %s default: %w", cloudflaredOpenRCService, err)
	}
	if err := runCommand("rc-service", cloudflaredOpenRCService, "start"); err != nil {
		return fmt.Errorf("rc-service %s start: %w", cloudflaredOpenRCService, err)
	}
	return nil
}

func uninstallLinuxService(c *cli.Context) error {
	log := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)

	var err error
	switch {
	case inits.IsSystemd():
		log.Info().Msg("Using Systemd")
		err = uninstallSystemd(log)
	case inits.IsOpenRC():
		log.Info().Msg("Using OpenRC")
		err = uninstallOpenRC(log)

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Re-run the install as root (sudo cloudflared service install)
  2. Verify rc-update exists: `which rc-update`; if absent, the distro doesn't use OpenRC — install via systemd or sysv instead, or install OpenRC
  3. Confirm /etc/init.d/cloudflared exists and is executable; if not, fix the template generation step or regenerate with cloudflared service install
  4. Run `rc-update add cloudflared default` manually to see the raw error output
  5. Check the wrapped error (%w) in the message for the exact rc-update exit cause

Example fix

// before: installing on a non-OpenRC distro fails
$ cloudflared service install
// error: rc-update add cloudflared default: exec: "rc-update": executable file not found
// after: use the correct init system or install OpenRC first
$ sudo cloudflared service install   # on Gentoo/Alpine with OpenRC present
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check before running `cloudflared service install` on OpenRC systems
if _, err := exec.LookPath("rc-update"); err != nil {
    return errors.New("rc-update not found: this system does not use OpenRC; install as root on Gentoo/Alpine")
}
if os.Geteuid() != 0 {
    return errors.New("service install requires root; re-run with sudo")
}
if _, err := os.Stat("/etc/init.d/cloudflared"); err != nil {
    return fmt.Errorf("init script missing; template generation failed: %w", err)
}

Type guard

func isOpenRCAvailable() bool {
    if os.Geteuid() != 0 { return false }
    if _, err := exec.LookPath("rc-update"); err != nil { return false }
    _, err := os.Stat("/etc/init.d/cloudflared")
    return err == nil
}

Try / catch

// caller-side handling of the install error
if err := installLinuxService(c); err != nil {
    var exitErr *exec.ExitError
    if errors.As(err, &exitErr) {
        log.Errorf("rc-update failed (exit %d); check init script and root privileges: %v", exitErr.ExitCode(), err)
    } else if strings.Contains(err.Error(), "executable file not found") {
        log.Error("rc-update missing: not an OpenRC system; use systemd/sysv install path")
    }
    return err
}

Prevention

When it happens

Trigger: `cloudflared service install` on a Linux distro using OpenRC when runCommand("rc-update", "add", cloudflaredOpenRCService, "default") returns a non-zero exit status — e.g. rc-update is not installed, the user is not root, or the OpenRC init script was never generated/doesn't exist.

Common situations: Running `cloudflared service install` without sudo on Gentoo/Alpine; a minimal container or chroot without a real OpenRC installation; the openrcTemplate.Generate step silently succeeded but the /etc/init.d/cloudflared file was later removed; corrupted or partial OpenRC installation where the default runlevel symlink target is missing.

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/8c25b2ee9c8f26af. Report an issue: GitHub.