unionlabs/union · critical

failed to read upgrade info from disk %s

Error message

failed to read upgrade info from disk %s

What it means

At app construction, setupUpgradeStoreLoaders calls ReadUpgradeInfoFromDisk, which reads <home>/data/upgrade-info.json. A missing file is normal (empty info, no store loader set); an unreadable or malformed file makes the call return an error and the app panics before the node starts. The message embeds the underlying error via %s.

Source

Thrown at uniond/app/upgrades.go:20

import (
	"fmt"

	upgradetypes "cosmossdk.io/x/upgrade/types"

	"github.com/unionlabs/union/uniond/app/upgrades"
	"github.com/unionlabs/union/uniond/app/upgrades/v1_1_0"
	"github.com/unionlabs/union/uniond/app/upgrades/v1_2_0"
	"github.com/unionlabs/union/uniond/app/upgrades/v1_3_0"
)

var Upgrades = []upgrades.Upgrade{v1_1_0.Upgrade, v1_2_0.Upgrade, v1_3_0.Upgrade}

// configure store loader that checks if version == upgradeHeight and applies store upgrades
func (app *App) setupUpgradeStoreLoaders() {
	upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
	if err != nil {
		panic(fmt.Sprintf("failed to read upgrade info from disk %s", err))
	}

	if app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
		return
	}

	for _, upgrade := range Upgrades {
		if upgradeInfo.Name == upgrade.UpgradeName {
			app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &upgrade.StoreUpgrades))
		}
	}
}

func (app *App) setupUpgradeHandlers() {
	for _, upgrade := range Upgrades {
		app.UpgradeKeeper.SetUpgradeHandler(
			upgrade.UpgradeName,
			upgrade.CreateUpgradeHandler(

View on GitHub (pinned to 031785bb6d)

Solutions

  1. Inspect the file: jq . <home>/data/upgrade-info.json — the error's %s suffix tells you read vs parse failure
  2. If JSON is malformed and no upgrade is actually pending, remove or rename the file and restart (a missing file is treated as no pending upgrade)
  3. If an upgrade IS pending, fix the content to {"name":"<plan>","height":N} rather than deleting it
  4. Check permissions/ownership of the home dir and confirm the --home flag
Defensive patterns

Strategy: validation

Validate before calling

# Pre-flight the file cosmos-sdk reads at startup
f="$HOME/.union/data/upgrade-info.json"
if [ -f "$f" ]; then
  jq -e 'has("name") and has("height")' "$f" >/dev/null || echo "invalid upgrade-info.json — fix or remove before starting uniond"
  [ -r "$f" ] || echo "upgrade-info.json not readable by this user"
fi

Prevention

When it happens

Trigger: upgrade-info.json exists but contains invalid/truncated JSON (interrupted upgrade-height write), the process cannot read the data dir (permissions/ownership), or --home points at a data dir whose upgrade-info.json is broken.

Common situations: Crash or power loss while the upgrade module wrote the file; running the node under a different user than the one that owns the home dir; hand-edited upgrade-info.json; wrong --home flag after a data-dir move.

Related errors


AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16). Data as JSON: /api/errors/70f2bb6bb5c36364. Report an issue: GitHub.