gravitational/teleport · error
version is linked
Error message
version is linked
What it means
ErrLinked is the sentinel returned when an updater operation (remove, replace, install) attempts to modify a revision that is currently linked to a path — i.e. it is the active binary pointed at by the stable link. Deleting or replacing a linked revision would break the running installation, so the installer/updater refuse with ErrLinked wrapped with context.
Source
Thrown at lib/autoupdate/agent/updater.go:344
TryLinkSystem(ctx context.Context) error
// Unlink unlinks the specified revision of Teleport from path.
// Unlink must be idempotent.
Unlink(ctx context.Context, rev Revision, pathDir string) error
// UnlinkSystem unlinks the system (package) installation of Teleport from the system linking location.
// UnlinkSystem must be idempotent.
UnlinkSystem(ctx context.Context) error
// List the installed revisions of Teleport.
List(ctx context.Context) (revisions []Revision, err error)
// Remove the Teleport agent at revision.
// Remove must be idempotent.
Remove(ctx context.Context, rev Revision) error
// IsLinked returns true if the revision is linked to path.
IsLinked(ctx context.Context, rev Revision, pathDir string) (bool, error)
}
var (
// ErrLinked is returned when a linked version cannot be operated on.
ErrLinked = errors.New("version is linked")
// ErrNotSupported is returned when the operation is not supported on the platform.
ErrNotSupported = errors.New("not supported on this platform")
// ErrNotAvailable is returned when the operation is not available at the current version of the platform.
ErrNotAvailable = errors.New("not available at this version")
// ErrNoBinaries is returned when no binaries are available to be linked.
ErrNoBinaries = errors.New("no binaries available to link")
// ErrFilePresent is returned when a file is present.
ErrFilePresent = errors.New("file present")
// ErrNotInstalled is returned when Teleport is not installed.
ErrNotInstalled = errors.New("not installed")
)
// Process provides an API for interacting with a running Teleport process.
type Process interface {
// Name of the process.
Name() string
// Reload must reload the Teleport process as gracefully as possible.
// If the process is not healthy after reloading, Reload must return an error.View on GitHub (pinned to 1283425b60)
Solutions
- Check IsLinked(ctx, rev, pathDir) before removing/replacing and skip (or advance the link first) when it returns true.
- Re-link to a newer revision first (complete the upgrade), then retry the remove/replace of the old revision.
- If you truly want to remove the active revision, remove the stable link pointing at it before calling Remove — at your own risk.
- Update to a newer Teleport version if this arises during a normal upgrade flow; link handling may have been fixed.
Example fix
// before
if err := u.Installer.Remove(ctx, rev); err != nil { return err }
// after
linked, _ := u.Installer.IsLinked(ctx, rev, binDir)
if !linked {
if err := u.Installer.Remove(ctx, rev); err != nil { return err }
} Defensive patterns
Strategy: validation
Validate before calling
// Guard before mutating a revision:
linked, err := inst.IsLinked(ctx, rev, binDir)
if err != nil { return err }
if linked { return nil } // skip remove/replace Type guard
func isLinkedErr(err error) bool { return errors.Is(err, agent.ErrLinked) } Try / catch
err := u.Installer.Remove(ctx, rev)
if errors.Is(err, agent.ErrLinked) {
// advance the link to a newer revision, then retry
} Prevention
- Always call IsLinked before Remove or Replace.
- Complete link advancement to a new revision before pruning old ones.
- Avoid manually editing the versions directory or stable links.
When it happens
Trigger: Calling Installer.Remove(ctx, rev) for a revision where IsLinked is true (updater.go:1027 returns trace.Wrap(ErrLinked, "refusing to remove")); or Installer.Replace targeting newname where the existing name at the target is still the linked oldname (installer.go:1075 returns trace.Wrap(ErrLinked, "refusing to replace link at %s", newname)).
Common situations: Attempting to prune old revisions while the target revision is the currently active link; re-running an install/upgrade where the link was never advanced past the old revision; manual manipulation of the versions directory that leaves a linked revision in the way of a replace.
Related errors
- executable has unstable path
- 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/90e1642613ec37aa.
Report an issue: GitHub.