gravitational/teleport · error

file present

Error message

file present

What it means

ErrFilePresent signals that the updater refuses to replace a file at the target path because it belongs to a non-linked (independently installed) Teleport, and the operation was not run with force. It is a safety guard against clobbering a manually installed binary. The wrap message includes the refused path, e.g. 'refusing to replace file at /usr/local/bin/teleport'.

Source

Thrown at lib/autoupdate/agent/updater.go:352

	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.
	// If the process did not require reloading, Reload must return ErrNotNeeded.
	// E.g., if the process is not enabled, or it was already reloaded after the last Sync.
	// If the type implementing Process does not support the system process manager,
	// Reload must return ErrNotSupported.
	Reload(ctx context.Context) error
	// Sync must validate and synchronize process configuration.
	// After the linked Teleport installation is changed, failure to call Sync without
	// error before Reload may result in undefined behavior.

View on GitHub (pinned to 1283425b60)

Solutions

  1. Remove the non-linked binary at the reported path (or uninstall the deb/rpm package) so teleport-update can manage it.
  2. Re-run the operation with the force flag if you intentionally want to replace the existing file.
  3. Verify ownership of the conflicting file (`ls -l <path>`) and confirm it is not needed before forcing.
  4. Standardize on one install method per host to avoid recurrence.

Example fix

// before
_, err := installer.link(ctx, target) // fails: refusing to replace file at /usr/bin/teleport
// after
// remove the unmanaged install first
// $ sudo apt-get remove teleport  (or delete /usr/bin/teleport)
_, err := installer.link(ctx, target) // succeeds
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Lstat(newname); err == nil {
    // target exists: confirm it belongs to a linked install or plan removal/force
}

Type guard

func IsFilePresent(err error) bool { return errors.Is(err, autoupdate.ErrFilePresent) }

Try / catch

if _, err := installer.link(ctx, target); err != nil {
    if errors.Is(err, autoupdate.ErrFilePresent) {
        return fmt.Errorf("unmanaged install at %s; remove it or use force", target)
    }
    return trace.Wrap(err)
}

Prevention

When it happens

Trigger: installer.go:848 — during link/upgrade, os.Link-style replacement hits an existing target that is not part of the linked install and force is not set; installer.go:1066 — rename fails with EEXIST/EINVAL indicating the target file already exists unmanaged.

Common situations: A Teleport binary was installed via a system package (deb/rpm) or copied manually to /usr/local/bin, and teleport-update then tries to manage the same path; mixing install methods (package manager + teleport-update) on one host.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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