dagger/dagger · error

failed to get mtime of updated bundle: %w

Error message

failed to get mtime of updated bundle: %w

What it means

During commonInstaller.Install at engine/engineutil/cacerts/distros.go:417, errors from d.ctrFS.MtimeOf(d.bundlePath) after the update command ran are wrapped with this message. The updated mtime is captured so the library can detect whether the update tool actually regenerated the bundle. It fires when the bundle's mtime cannot be read after the updater supposedly produced/refreshed it.

Source

Thrown at engine/engineutil/cacerts/distros.go:417

		if err := d.ctrFS.WriteFile(destPath, []byte(certContents+"\n"), 0644); err != nil {
			return err
		}
		cleanups.append(func() error {
			return d.ctrFS.Remove(destPath)
		})
	}

	if d.updateCommandExisted {
		// prepend cleanup instead of append so uninstall runs last after other cleanups have ran
		cleanups.prepend(func() error {
			return d.ctrFS.Exec(ctx, d.updateCmd...)
		})
		if err := d.ctrFS.Exec(ctx, d.updateCmd...); err != nil {
			return fmt.Errorf("failed to run %v for install: %w", d.updateCmd, err)
		}
		d.updatedBundleMtime, err = d.ctrFS.MtimeOf(d.bundlePath)
		if err != nil {
			return fmt.Errorf("failed to get mtime of updated bundle: %w", err)
		}
		return nil
	}

	if d.bundleExisted {
		origBundleContents, err := d.ctrFS.ReadFile(d.bundlePath)
		if err != nil {
			return fmt.Errorf("failed to read existing bundle: %w", err)
		}
		cleanups.append(func() error {
			if err := d.ctrFS.WriteFile(d.bundlePath, origBundleContents, 0644); err != nil {
				return err
			}
			if err := d.ctrFS.SetMtime(d.bundlePath, d.originalBundleMtime); err != nil {
				return fmt.Errorf("failed to set mtime of bundle during install: %w", err)
			}
			return nil
		})

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Check that bundlePath resolves to a real file after running the update tool manually.
  2. Fix the distro bundle symlink so it points at the updater's output path.
  3. Ensure no concurrent process removes the bundle between the update exec and mtime read.
  4. Retry Install if the stat failure was transient.

Example fix

// before: dangling bundle symlink after updater ran
ls -l /etc/ssl/certs/ca-certificates.crt -> /etc/ssl/certs/old-bundle.pem (missing)
// after
ln -sf /etc/ca-certificates/extracted/tls-ca-bundle.pem /etc/ssl/certs/ca-certificates.crt
Defensive patterns

Strategy: try-catch

Validate before calling

// after a manual run of the updater, confirm the bundle still resolves
readlink -f /etc/ssl/certs/ca-certificates.crt || echo 'bundle symlink broken'

Type guard

func resolves(path string) bool {
	resolved, err := filepath.EvalSymlinks(path)
	return err == nil && resolved != ""
}

Try / catch

err := installer.Install(ctx)
if err != nil && strings.Contains(err.Error(), "failed to get mtime of updated bundle") {
	// updater removed/retargeted the bundle; restore it and retry
}

Prevention

When it happens

Trigger: updateCommandExisted==true, the update command succeeded, then MtimeOf(bundlePath) fails: the updater deleted the bundle instead of updating it, the bundle is a dangling symlink, or stat permission/I/O error.

Common situations: Distro updater regenerates the bundle at a different path (symlink retargeted), leaving a dangling link; concurrent cleanup removed the bundle; restricted FS after exec.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/af7722e6ce7b598e. Report an issue: GitHub.