{"record":{"id":"5ddad78dfc31114b","repo":"containerd/containerd","slug":"failed-to-initialize-database-w","errorCode":null,"errorMessage":"failed to initialize database: %w","messagePattern":"failed to initialize database: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"plugins/snapshots/devmapper/metadata.go","lineNumber":74,"sourceCode":"\tErrAlreadyExists = errdefs.ErrAlreadyExists\n)\n\n// PoolMetadata keeps device info for the given thin-pool device, generates next available device ids,\n// and tracks devmapper transaction numbers\ntype PoolMetadata struct {\n\tdb *bolt.DB\n}\n\n// NewPoolMetadata creates new or opens existing pool metadata database\nfunc NewPoolMetadata(dbfile string) (*PoolMetadata, error) {\n\tdb, err := bolt.Open(dbfile, 0600, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmetadata := &PoolMetadata{db: db}\n\tif err := metadata.ensureDatabaseInitialized(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to initialize database: %w\", err)\n\t}\n\n\treturn metadata, nil\n}\n\n// ensureDatabaseInitialized creates buckets required for metadata store in order\n// to avoid bucket existence checks across the code\nfunc (m *PoolMetadata) ensureDatabaseInitialized() error {\n\treturn m.db.Update(func(tx *bolt.Tx) error {\n\t\tif _, err := tx.CreateBucketIfNotExists(devicesBucketName); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif _, err := tx.CreateBucketIfNotExists(deviceIDBucketName); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/plugins/snapshots/devmapper/metadata.go#L56-L92","documentation":"NewPoolMetadata wraps any failure from ensureDatabaseInitialized, which opens/creates the bolt DB and creates the required buckets (devices, deviceids, poolmeta) for the devmapper metadata store. It means the persistent metadata database could not be set up, so the snapshotter pool cannot track devices. The underlying bolt error (I/O error, corrupt file, permission denied) is preserved via %w.","triggerScenarios":"Calling NewPoolMetadata (directly or through createStore/NewPoolDevice when starting the devmapper snapshotter) when the DB file cannot be opened with read-write access, is corrupted, or ensureDatabaseInitialized fails to create the required buckets.","commonSituations":"DB file on a read-only volume; snapshotter root path owned by a different user after a containerd upgrade; disk full; leftover corrupt db from an unclean shutdown; running two containerd instances pointed at the same metadata.db.","solutions":["Check permissions/ownership of the devmapper snapshotter root path and its metadata.db file; ensure the containerd user has read-write access.","Confirm the filesystem holding the DB is writable and not full (df, mount | grep ro).","If the DB is corrupt or from an incompatible version, stop containerd, back up and remove metadata.db, and let the snapshotter recreate it (devices will need reactivation).","Ensure only one containerd instance uses this pool; check for stale lock holders."],"exampleFix":"// before\nsnapshotter root: /var/lib/containerd/io.containerd.snapshotter.v1.devmapper (owned by root, containerd runs as user)\n// after\nchown -R containerd:containerd /var/lib/containerd/io.containerd.snapshotter.v1.devmapper","handlingStrategy":"validation","validationCode":"dbPath := filepath.Join(rootDir, \"metadata.db\")\nif fi, err := os.Stat(filepath.Dir(dbPath)); err != nil || !fi.IsDir() {\n    return fmt.Errorf(\"snapshotter root missing: %s\", rootDir)\n}\nif f, err := os.OpenFile(dbPath, os.O_RDWR, 0o600); err != nil {\n    return fmt.Errorf(\"metadata.db not writable: %w\", err)\n} else {\n    f.Close()\n}","typeGuard":null,"tryCatchPattern":"md, err := devmapper.NewPoolMetadata(ctx, dbPath)\nif err != nil {\n    return fmt.Errorf(\"check metadata.db path permissions/disk and that no other containerd holds it: %w\", err)\n}","preventionTips":["Ensure the containerd user owns the devmapper snapshotter root directory.","Mount the metadata volume read-write and monitor free space.","Never run two containerd instances against the same pool/DB.","Back up metadata.db before containerd upgrades."],"tags":["devmapper","bolt","database","initialization"],"backgroundTag":"database-initialization-failed","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}