gravitational/teleport · warning
executable has unstable path
Error message
executable has unstable path
What it means
ErrUnstableExecutable is returned by StableExecutable/stablePathForBinary when a stable, version-independent path to the Teleport binary cannot be resolved. The unstable path (from os.Executable()) is still returned alongside the error so callers can proceed, but the path points at a specific versioned binary that may disappear after an update.
Source
Thrown at lib/autoupdate/agent/integrations.go:40
"context"
"errors"
"io/fs"
"log/slog"
"os"
"path/filepath"
"github.com/google/uuid"
"github.com/gravitational/trace"
"github.com/gravitational/teleport/api/types"
)
var (
// ErrConfigNotFound is returned by HellorUpdaterInfo when the updater config file cannot be found.
ErrConfigNotFound = errors.New("updater config file not found")
// ErrUnstableExecutable is returned by StableExecutable when no stable path can be found.
ErrUnstableExecutable = errors.New("executable has unstable path")
)
const updateConfigFileEnvVar = "TELEPORT_UPDATE_CONFIG_FILE"
// IsManagedByUpdater returns true if the local Teleport binary is managed by teleport-update.
// Note that true may be returned even if auto-updates is disabled or the version is pinned.
// The binary is considered managed if it lives under /opt/teleport, but not within the package
// path at /opt/teleport/system.
func IsManagedByUpdater() (bool, error) {
systemd, err := hasSystemD()
if err != nil {
return false, trace.Wrap(err)
}
if !systemd {
return false, nil
}
teleportPath, err := os.Executable()
if err != nil {View on GitHub (pinned to 1283425b60)
Solutions
- For package installs, recreate the stable symlink: ln -s /opt/teleport/system/bin/teleport /usr/local/bin/teleport (matching name).
- For Managed Updates, inspect update.yaml (cfg.Spec.Path) and ensure the path exists and contains the binary; re-run teleport-update to repair links.
- Re-run the installer/upgrade to restore the stable link path, or hard-restart the service so it resolves the new binary.
- Handle the error in callers: use the returned unstable path but treat it as ephemeral — do not persist it across updates.
Example fix
// before
p, err := autoupdate.StableExecutable()
if err != nil { return err }
// after
p, err := autoupdate.StableExecutable()
if errors.Is(err, autoupdate.ErrUnstableExecutable) {
// p is still valid but version-specific; use it, don't persist it
} else if err != nil {
return err
} Defensive patterns
Strategy: type-guard
Validate before calling
// Pre-check the stable link before calling:
if _, err := os.Stat("/usr/local/bin/teleport"); err != nil {
// stable link missing: repair it or expect ErrUnstableExecutable
} Type guard
func isUnstableExecutable(err error) bool { return errors.Is(err, autoupdate.ErrUnstableExecutable) } Try / catch
p, err := autoupdate.StableExecutable()
switch {
case errors.Is(err, autoupdate.ErrUnstableExecutable):
// p is valid but version-specific; use ephemeral, do not persist
case err != nil:
return trace.Wrap(err)
} Prevention
- Keep /usr/local/bin/<name> symlinks intact for package installs.
- Verify cfg.Spec.Path in update.yaml exists after every upgrade.
- Never treat the path returned with ErrUnstableExecutable as durable across updates.
When it happens
Trigger: Calling StableExecutable when: (1) the binary lives in a package install (<packageSystemDir>/bin/<name>) but /usr/local/bin/<name> does not exist or does not stat (integrations.go:103); or (2) the binary is a Managed Updates install and update.yaml exists but cfg.Spec.Path is empty or the target link path <cfg.Spec.Path>/<name> fails os.Stat (integrations.go:122).
Common situations: Package (deb/rpm) installs where the /usr/local/bin symlink was deleted or never created; Managed Updates installs whose update.yaml points to a path that was moved, deleted, or never linked; partially completed upgrades leaving the versions dir without a working stable link.
Related errors
- version is linked
- updater config file not found
- not supported on this platform
- no binaries available to link
- file present
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/4da5c536aff67304.
Report an issue: GitHub.