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

  1. Check IsLinked(ctx, rev, pathDir) before removing/replacing and skip (or advance the link first) when it returns true.
  2. Re-link to a newer revision first (complete the upgrade), then retry the remove/replace of the old revision.
  3. If you truly want to remove the active revision, remove the stable link pointing at it before calling Remove — at your own risk.
  4. 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

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


AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02). Data as JSON: /api/errors/90e1642613ec37aa. Report an issue: GitHub.