ipfs/kubo · error

no stashed binaries found in %s

Error message

no stashed binaries found in %s

What it means

`findLatestStash` throws this when the stash directory was readable but contained no files matching the `ipfs-<semver>` naming convention, so there is no backed-up binary to revert to. Kubo stashes the previous binary during `ipfs update`; without one, rollback is impossible.

Source

Thrown at core/commands/update.go:697

			return -1
		}
		if b.parsed.GreaterThan(a.parsed) {
			return 1
		}
		return 0
	})

	return stashes, nil
}

// findLatestStash finds the most recently versioned stash file.
func findLatestStash(dir string) (path, ver string, err error) {
	stashes, err := listStashes(dir)
	if err != nil {
		return "", "", fmt.Errorf("reading stash directory: %w", err)
	}
	if len(stashes) == 0 {
		return "", "", fmt.Errorf("no stashed binaries found in %s", dir)
	}
	return stashes[0].path, stashes[0].ver, nil
}

// replaceBinary atomically replaces the binary at targetPath with data.
func replaceBinary(targetPath string, data []byte) error {
	af, err := atomicfile.New(targetPath, 0o755)
	if err != nil {
		return err
	}

	if _, err := af.Write(data); err != nil {
		_ = af.Abort()
		return err
	}

	return af.Close()
}

View on GitHub (pinned to 329838acdf)

Solutions

  1. List what is actually there: `ls -la "$IPFS_PATH/stash"` — confirm no `ipfs-*` files exist.
  2. If the desired version's stash file exists under a wrong name, rename it to the convention: `ipfs-<semver>` (e.g. `ipfs-0.29.0`).
  3. If there is genuinely no stash, reinstall the target version directly (download from dist.ipfs.tech or your package manager) instead of reverting.
  4. Avoid `ipfs update clean` if you want to keep rollback ability for the current version.

Example fix

# before: stash emptied, revert impossible
ipfs update clean
ipfs update revert   # no stashed binaries found in /home/u/.ipfs/stash

# after: install the desired version explicitly
ipfs update install v0.29.0
Defensive patterns

Strategy: fallback

Validate before calling

entries, _ := os.ReadDir(filepath.Join(repoPath, "stash"))
hasStash := false
for _, e := range entries {
	if strings.HasPrefix(e.Name(), "ipfs-") {
		hasStash = true
		break
	}
}
if !hasStash {
	// no rollback possible: plan a direct install of the target version instead
}

Type guard

func hasAnyStash(dir string) bool {
	entries, err := os.ReadDir(dir)
	if err != nil {
		return false
	}
	return slices.ContainsFunc(entries, func(e os.DirEntry) bool {
		return strings.HasPrefix(e.Name(), "ipfs-")
	})
}

Try / catch

path, ver, err := findLatestStash(dir)
if err != nil {
	if strings.Contains(err.Error(), "no stashed binaries") {
		// fallback: download and install the desired version directly
		return installDirectly(targetVersion)
	}
	return err
}

Prevention

When it happens

Trigger: `ipfs update revert` (or code paths calling findLatestStash) when no update has ever run, the stash was emptied by `ipfs update clean`, stash files were manually deleted/renamed, or only files not matching the `ipfs-<version>` pattern exist in the directory.

Common situations: Reverting on a fresh install; running `update clean` then trying to revert; user files placed in the stash dir that don't parse as versions; updates installed from a dist file without stashing.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/b6671381168c7b2e. Report an issue: GitHub.