henrygd/beszel · warning
no SELinux tools available (semanage/restorecon or chcon)
Error message
no SELinux tools available (semanage/restorecon or chcon)
What it means
HandleSELinuxContext first tries persistent SELinux relabeling via semanage/restorecon, then falls back to chcon. If none of these tools can be found on PATH (exec.LookPath fails for chcon as the last fallback), it returns this error. It indicates an SELinux system (or one the function treats as such) with no available tooling to apply a bin_t context.
Source
Thrown at internal/ghupdate/selinux.go:36
return nil
}
ColorPrint(ColorYellow, "SELinux is enabled; applying context…")
// Try persistent context via semanage+restorecon
if success := trySemanageRestorecon(path); success {
return nil
}
// Fallback to temporary context via chcon
if chconPath, err := exec.LookPath("chcon"); err == nil {
if err := exec.Command(chconPath, "-t", "bin_t", path).Run(); err != nil {
return fmt.Errorf("chcon failed: %w", err)
}
return nil
}
return fmt.Errorf("no SELinux tools available (semanage/restorecon or chcon)")
}
// trySemanageRestorecon attempts to set persistent SELinux context using semanage and restorecon.
// Returns true if successful, false otherwise.
func trySemanageRestorecon(path string) bool {
semanagePath, err := exec.LookPath("semanage")
if err != nil {
return false
}
restoreconPath, err := exec.LookPath("restorecon")
if err != nil {
return false
}
// Try to add the fcontext rule; if it already exists, try to modify it
if err := exec.Command(semanagePath, "fcontext", "-a", "-t", "bin_t", path).Run(); err != nil {
// Rule may already exist, try modify insteadView on GitHub (pinned to b38fb7dafa)
Solutions
- Install SELinux userland tools: `dnf install policycoreutils-python-utils` (semanage/restorecon) or at minimum `yum install policycoreutils` (chcon).
- Ensure PATH includes /usr/sbin and /sbin when running from systemd/cron, since SELinux tools often live there.
- If the host does not use SELinux, guard the call so HandleSELinuxContext is skipped (e.g. check /sys/fs/selinux exists) — this error is expected on non-SELinux systems.
- Relabel manually after update: `sudo chcon -t bin_t /path/to/binary`.
Example fix
// before: minimal container without SELinux tools
// error: no SELinux tools available (semanage/restorecon or chcon)
// after: install tooling or skip when SELinux is absent
if _, err := os.Stat("/sys/fs/selinux"); err == nil {
if err := HandleSELinuxContext(binPath); err != nil { log.Warn(err) }
} Defensive patterns
Strategy: fallback
Validate before calling
func selinuxManaged() bool {
if _, err := os.Stat("/sys/fs/selinux"); err != nil { return false }
for _, t := range []string{"semanage", "restorecon", "chcon"} {
if _, err := exec.LookPath(t); err == nil { return true }
}
return false
}
// call HandleSELinuxContext only if selinuxManaged() Type guard
func hasAnySELinuxTool() bool {
for _, t := range []string{"semanage", "restorecon", "chcon"} {
if p, _ := exec.LookPath(t); p != "" { return true }
}
return false
} Try / catch
err := HandleSELinuxContext(binPath)
if err != nil && strings.Contains(err.Error(), "no SELinux tools available") {
log.Info("SELinux tooling absent; skipping context fix")
return nil
} Prevention
- Skip the call on non-SELinux systems (check /sys/fs/selinux) — this error is expected there.
- Bake SELinux userland into container images if relabeling is required at runtime.
- Ensure PATH includes /usr/sbin for systemd/cron-launched updaters.
- Provide a manual relabel step in deployment docs as fallback.
When it happens
Trigger: Calling HandleSELinuxContext on a host where neither semanage, restorecon, nor chcon is installed or on PATH. Tests TestHandleSELinuxContext_NoSELinux and TestHandleSELinuxContext_InvalidPath exercise this path.
Common situations: Minimal/scratch container images or distroless systems without SELinux userland; running from an environment with a stripped PATH (cron, systemd unit with minimal Environment); SELinux utilities simply never installed on the host.
Related errors
AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31).
Data as JSON: /api/errors/f318312507e357c6.
Report an issue: GitHub.