hyperledger/fabric · critical
unexpected data version - cannot upgrade data format for pvt
Error message
unexpected data version - cannot upgrade data format for pvtdatastore from %s to %s
What it means
CheckAndConstructHashedIndex inspects the pvtdatastore's recorded format version; it can only upgrade data version 1.0 to 2.5 by retroactively building the hashed index. If the stored version is neither the old version nor the current one, the on-disk private data store is in an unrecognized state and the provider refuses to open it rather than corrupting data.
Source
Thrown at core/ledger/pvtdatastorage/retroactive_hashed_index.go:43
func CheckAndConstructHashedIndex(storePath string, ledgerIDs []string) error {
info, err := leveldbhelper.RetrieveDataFormatInfo(storePath)
if err != nil {
return err
}
if info.IsDBEmpty || info.FormatVerison == currentDataVersion {
return nil
}
if info.FormatVerison == previousDataVersion {
if err := constructHashedIndex(storePath, ledgerIDs); err != nil {
return err
}
return nil
}
return errors.Errorf("unexpected data version - cannot upgrade data format for pvtdatastore from %s to %s", info.FormatVerison, currentDataVersion)
}
// constructHashedIndex creates the HashedIndex entries for the private data keys and at the end sets the
// data format version to the current version (2.5)
func constructHashedIndex(storePath string, ledgerIDs []string) error {
p, err := leveldbhelper.NewProvider(
&leveldbhelper.Conf{
DBPath: storePath,
ExpectedFormat: previousDataVersion,
},
)
if err != nil {
return err
}
defer p.Close()
for _, l := range ledgerIDs {View on GitHub (pinned to 2736b63f8f)
Solutions
- Run the peer with a binary whose version is >= the version that wrote the datastore (never downgrade across the data-version change).
- Restore the pvtdatastore from a consistent backup taken with the same version, or delete and rebuild it (e.g. re-join the channel) if the data is dispensable.
- If the version record is corrupt, rebuild the private data store from block/pvtdata sources or a fresh snapshot join.
Example fix
// before: peer binary v2.4 opening a datastore written by v2.5 // after: upgrade the peer binary to match/exceed the datastore version // (or rebuild: stop peer, move pvtdatastore aside, re-join channel by snapshot/genesis)
Defensive patterns
Strategy: validation
Validate before calling
info, err := pvtdatastore.ReadFormatVersion(storePath)
if err != nil { return err }
if info.FormatVerison != "1.0" && info.FormatVerison != currentDataVersion {
return fmt.Errorf("unsupported pvtdatastore version %s; use matching peer binary", info.FormatVerison)
} Try / catch
if err := CheckAndConstructHashedIndex(storePath, ledgerIDs); err != nil {
if strings.Contains(err.Error(), "unexpected data version") {
// halt startup; require matching binary version or rebuild of pvtdatastore
}
return err
} Prevention
- Never downgrade the peer binary below the version that wrote the datastore.
- Keep consistent backups of pvtdatastore taken by the same Fabric version.
- Check release notes for pvtdatastore data-version changes before upgrading/restoring.
When it happens
Trigger: Opening a peer whose pvtdatastore directory reports a FormatVerison other than the legacy 1.0 or the current version — e.g. a datastore from a newer/older Fabric version, a corrupted version record, or a partially upgraded datastore.
Common situations: Downgrading a peer to a Fabric version whose currentDataVersion is lower than what the datastore was written with; restoring the pvtdatastore from an unknown/mixed backup; corruption of the store's metadata after a crash.
Related errors
- global OrdererAddresses are not allowed with V3_0 capability
- unexpected end of blockfile
- error opening block file %s
- error seeking block file [%s] to startOffset [%d]
- Could not seek block file [%s] to startOffset [%d]. New posi
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/7ce8b40e6d8acd6e.
Report an issue: GitHub.