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
- Re-run the install as root (sudo cloudflared service install)
- Verify rc-update exists: `which rc-update`; if absent, the distro doesn't use OpenRC — install via systemd or sysv instead, or install OpenRC
- Confirm /etc/init.d/cloudflared exists and is executable; if not, fix the template generation step or regenerate with cloudflared service install
- Run `rc-update add cloudflared default` manually to see the raw error output
- 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
- Always run service install/uninstall with sudo
- Detect the init system first (systemd vs OpenRC vs sysv) and use the matching install path
- Verify the init script was generated before registering it with rc-update
- On minimal containers, prefer running cloudflared directly instead of installing a service
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
- error generating OpenRC conf.d template: %w
- error generating OpenRC service template: %w
- rc-service %s start: %w
- error resolving OpenRC template path: %w
- error removing %s: %w
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/8c25b2ee9c8f26af.
Report an issue: GitHub.