{"record":{"id":"2d7db7a2ffa0c449","repo":"dgraph-io/badger","slug":"errinvalidkey","errorCode":"ErrInvalidKey","errorMessage":"Key is using a reserved !badger! prefix","messagePattern":"Key is using a reserved !badger! prefix","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"errors.go","lineNumber":44,"sourceCode":"\t// ErrTxnTooBig is returned if too many writes are fit into a single transaction.\n\tErrTxnTooBig = stderrors.New(\"Txn is too big to fit into one request\")\n\n\t// ErrConflict is returned when a transaction conflicts with another transaction. This can\n\t// happen if the read rows had been updated concurrently by another transaction.\n\tErrConflict = stderrors.New(\"Transaction Conflict. Please retry\")\n\n\t// ErrReadOnlyTxn is returned if an update function is called on a read-only transaction.\n\tErrReadOnlyTxn = stderrors.New(\"No sets or deletes are allowed in a read-only transaction\")\n\n\t// ErrDiscardedTxn is returned if a previously discarded transaction is reused.\n\tErrDiscardedTxn = stderrors.New(\"This transaction has been discarded. Create a new one\")\n\n\t// ErrEmptyKey is returned if an empty key is passed on an update function.\n\tErrEmptyKey = stderrors.New(\"Key cannot be empty\")\n\n\t// ErrInvalidKey is returned if the key has a special !badger! prefix,\n\t// reserved for internal usage.\n\tErrInvalidKey = stderrors.New(\"Key is using a reserved !badger! prefix\")\n\n\t// ErrBannedKey is returned if the read/write key belongs to any banned namespace.\n\tErrBannedKey = stderrors.New(\"Key is using the banned prefix\")\n\n\t// ErrThresholdZero is returned if threshold is set to zero, and value log GC is called.\n\t// In such a case, GC can't be run.\n\tErrThresholdZero = stderrors.New(\n\t\t\"Value log GC can't run because threshold is set to zero\")\n\n\t// ErrNoRewrite is returned if a call for value log GC doesn't result in a log file rewrite.\n\tErrNoRewrite = stderrors.New(\n\t\t\"Value log GC attempt didn't result in any cleanup\")\n\n\t// ErrRejected is returned if a value log GC is called either while another GC is running, or\n\t// after DB::Close has been called.\n\tErrRejected = stderrors.New(\"Value log GC request rejected\")\n\n\t// ErrInvalidRequest is returned if the user request is invalid.","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/errors.go#L26-L62","documentation":"ErrInvalidKey is returned when a user key uses the reserved '!badger!' prefix, which Badger keeps for internal keys (like !badger!head). Txn.modify rejects any key with that prefix (txn.go:360) to protect internal metadata.","triggerScenarios":"txn.Set/NewEntry with keys like \"!badger!head\" or \"!badger!\" (db_test.go:1124/1127); copying external data whose keys happen to start with !badger!. Note \"!badger\" (no trailing '!') is allowed.","commonSituations":"Importing datasets from other stores, generating keys from user input that collides with the prefix, probing internal keys from user code.","solutions":["Rename user keys so they don't start with '!badger!' (e.g. add an app prefix like 'app:')","Sanitize/validate incoming keys before writing","If you need internal data access, use the documented APIs instead of raw keys"],"exampleFix":"// before\ndb.Update(func(txn *Txn) error {\n    return txn.SetEntry(NewEntry([]byte(\"!badger!head\"), val)) // ErrInvalidKey\n})\n// after\ndb.Update(func(txn *Txn) error {\n    return txn.SetEntry(NewEntry([]byte(\"app!badger!head\"), val))\n})","handlingStrategy":"validation","validationCode":"if bytes.HasPrefix(key, []byte(\"!badger!\")) {\n    return fmt.Errorf(\"key %q uses reserved prefix\", key)\n}","typeGuard":"func isReservedKey(key []byte) bool {\n    return bytes.HasPrefix(key, []byte(\"!badger!\"))\n}","tryCatchPattern":"if err := txn.Set(key, val); err != nil {\n    if errors.Is(err, badger.ErrInvalidKey) {\n        return fmt.Errorf(\"rename key %q: uses reserved !badger! prefix\", key)\n    }\n    return err\n}","preventionTips":["Namespace all user keys with an app-specific prefix (e.g. 'app:')","Sanitize externally imported keys before writing","Add a reserved-prefix check to your key-construction tests"],"tags":["badger","validation","reserved-prefix","key"],"backgroundTag":"reserved-key-prefix","analyzedSha":"2a001d466f6b71a917319a1db41f99860e16e269","analyzedAt":"2026-09-05T13:00:02.264Z","contentChangedAt":"2026-09-05T13:00:02.264Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}