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
- Inspect the file: jq . <home>/data/upgrade-info.json — the error's %s suffix tells you read vs parse failure
- 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)
- If an upgrade IS pending, fix the content to {"name":"<plan>","height":N} rather than deleting it
- 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
- Never hand-edit upgrade-info.json
- Ensure the node process owns or can read <home>/data
- Back up the data dir before scheduled upgrade heights
- After a crash at an upgrade height, validate the file before restarting
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
- error while incrementing period: %w
- error while creating a new delegation period record: %w
- expected validator, not found
- newValAddr is not of type bytes.HexBytes
- newValPubKey is not of type crypto.PubKey
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/70f2bb6bb5c36364.
Report an issue: GitHub.