{"record":{"id":"7a9d93eb8482d301","repo":"hyperledger/fabric","slug":"error-retrieving-leveldb-key-v","errorCode":null,"errorMessage":"error retrieving leveldb key [%#v]","messagePattern":"error retrieving leveldb key \\[%#v\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/ledger/util/leveldbhelper/leveldb_helper.go","lineNumber":115,"sourceCode":"\t\treturn\n\t}\n\tif err := dbInst.db.Close(); err != nil {\n\t\tlogger.Errorf(\"Error closing leveldb: %s\", err)\n\t}\n\tdbInst.dbState = closed\n}\n\n// Get returns the value for the given key\nfunc (dbInst *DB) Get(key []byte) ([]byte, error) {\n\tdbInst.mutex.RLock()\n\tdefer dbInst.mutex.RUnlock()\n\tvalue, err := dbInst.db.Get(key, dbInst.readOpts)\n\tif errors.Is(err, leveldb.ErrNotFound) {\n\t\treturn nil, nil\n\t}\n\tif err != nil {\n\t\tlogger.Errorf(\"Error retrieving leveldb key [%#v]: %s\", key, err)\n\t\treturn nil, errors.Wrapf(err, \"error retrieving leveldb key [%#v]\", key)\n\t}\n\t// Previously the goleveldb library returned []byte{}\n\t// Now it returns []byte(nil)\n\t// NB!!! Because of the above changed behavior when there is no key in the database.\n\t// Here we simulate the desired behavior that the key is in the database.\n\tif value == nil {\n\t\tvalue = []byte{}\n\t}\n\treturn value, nil\n}\n\n// Put saves the key/value\nfunc (dbInst *DB) Put(key []byte, value []byte, sync bool) error {\n\tdbInst.mutex.RLock()\n\tdefer dbInst.mutex.RUnlock()\n\two := dbInst.writeOptsNoSync\n\tif sync {\n\t\two = dbInst.writeOptsSync","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/util/leveldbhelper/leveldb_helper.go#L97-L133","documentation":"DB.Get wraps any goleveldb Get error other than ErrNotFound (which is treated as a nil value, not an error) with the offending key. It means the key lookup failed for a reason other than absence: DB closed, corruption, or I/O error. Logged via logger.Errorf before being returned wrapped.","triggerScenarios":"Calling Get after the DB was closed; leveldb reports corruption in a data block; read I/O failure on the DB files; passing a nil/invalid key is possible but errors are usually storage-related.","commonSituations":"Using a DB handle after provider close during peer shutdown; corrupted leveldb after unclean shutdown; read-only or failing disk mounts.","solutions":["Check the wrapped error with errors.Is/errors.As for leveldb corruption or ErrClosed.","Ensure the DB instance is opened for the lifetime of all callers (no premature Close).","If corruption is reported, restore from backup or re-create the ledger database.","Verify disk/filesystem health and permissions on the DB path."],"exampleFix":"// before\nvalue, err := db.Get(key)\nif err != nil { return err }\n// after\nvalue, err := db.Get(key)\nif err != nil {\n  if errors.Is(err, leveldb.ErrClosed) {\n    return fmt.Errorf(\"leveldb closed before Get of key %#v\", key)\n  }\n  return err\n}","handlingStrategy":"try-catch","validationCode":"// ensure DB lifetime covers usage\ndb, err := openProvider()\nif err != nil { return err }\ndefer db.Close() // close only after all Gets are done","typeGuard":"func isGetErr(err error) bool {\n  return err != nil && strings.Contains(err.Error(), \"error retrieving leveldb key\")\n}","tryCatchPattern":"value, err := db.Get(key)\nif err != nil {\n  // ErrNotFound already returned as (nil, nil); anything here is a real failure\n  return fmt.Errorf(\"leveldb get of %#v failed: %w\", key, err)\n}","preventionTips":["Keep the DB open for the full lifetime of its users","Distinguish (nil, nil) 'not found' from wrapped errors","Back up leveldb data directories","Watch for disk errors in system logs"],"tags":["leveldb","storage","golang"],"backgroundTag":"leveldb-get-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}