{"record":{"id":"4f0823f45ba42f5f","repo":"caddyserver/caddy","slug":"configuring-acme-db-v","errorCode":null,"errorMessage":"configuring ACME DB: %v","messagePattern":"configuring ACME DB: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddypki/acmeserver/acmeserver.go","lineNumber":197,"sourceCode":"\t\t\t\t\tClaims: &provisioner.Claims{\n\t\t\t\t\t\tMinTLSDur:     &provisioner.Duration{Duration: 5 * time.Minute},\n\t\t\t\t\t\tMaxTLSDur:     &provisioner.Duration{Duration: 24 * time.Hour * 365},\n\t\t\t\t\t\tDefaultTLSDur: &provisioner.Duration{Duration: time.Duration(ash.Lifetime)},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tDB: database,\n\t}\n\n\tash.acmeAuth, err = ca.NewAuthority(authorityConfig)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tash.acmeDB, err = acmeNoSQL.New(ash.acmeAuth.GetDatabase().(nosql.DB))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"configuring ACME DB: %v\", err)\n\t}\n\n\tash.acmeClient, err = ash.makeClient()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tash.acmeLinker = acme.NewLinker(\n\t\tash.Host,\n\t\tstrings.Trim(ash.PathPrefix, \"/\"),\n\t)\n\n\t// extract its http.Handler so we can use it directly\n\tr := chi.NewRouter()\n\tr.Route(ash.PathPrefix, func(r chi.Router) {\n\t\tapi.Route(r)\n\t})\n\tash.acmeEndpoints = r","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddypki/acmeserver/acmeserver.go#L179-L215","documentation":"Returned when the smallstep ACME nosql layer (acmeNoSQL.New over the CA's bbolt database) fails to initialize its table schema on the ACME database. This happens during provisioning of the `acme_server` handler, after the authority is created. The %v wraps the underlying nosql/bbolt error (usually file open, permissions, or corruption).","triggerScenarios":"Two `acme_server` handlers pointed at the same CA but racing to init the DB during overlapping config loads; the data dir file ($AppDataDir/acme_server/&lt;key&gt;/db) is corrupt, truncated, or locked by another process; disk full or read-only filesystem where bbolt cannot create/open the file.","commonSituations":"Running Caddy in a container with the data dir on a read-only volume or a volume that lost data mid-write; migrating data dirs between Caddy versions; another Caddy instance or a leftover process holding a flock on the bbolt file; a previously killed Caddy leaving a torn db file.","solutions":["Check the wrapped cause — bbolt errors like `timeout` indicate the file is locked by another process; find and stop it","Verify write permissions on the storage path returned by `caddy list-modules`/AppDataDir (typically ~/.local/share/caddy/acme_server/&lt;ca-id&gt;/)","If the db file is corrupt and the CA data is expendable, stop Caddy, remove the acme_server/&lt;key&gt; folder (clients must re-enroll), and restart","Ensure only one Caddy instance uses the same data dir"],"exampleFix":"# before: read-only volume mount\ndocker run -v /caddy-data:/data:ro caddy\n\n# after: writable mount\ndocker run -v /caddy-data:/data caddy","handlingStrategy":"retry","validationCode":"// Pre-flight the database path before provisioning the handler:\ndir := filepath.Join(caddy.AppDataDir(), \"acme_server\", key)\nif f, err := os.OpenFile(filepath.Join(dir, \"db\"), os.O_RDWR, 0o600); err != nil {\n    return fmt.Errorf(\"acme db not writable: %w\", err)\n} else { f.Close() }","typeGuard":null,"tryCatchPattern":"// On provisioning failure, distinguish lock contention (retryable) from corruption (not):\nif err := ash.provision(); err != nil {\n    if strings.Contains(err.Error(), \"timeout\") || strings.Contains(err.Error(), \"locked\") {\n        time.Sleep(time.Second) // then retry once with backoff\n    } else {\n        return err // corrupt db / permissions: needs manual intervention\n    }\n}","preventionTips":["Ensure only one Caddy instance owns a given data dir","Mount the acme_server data dir on a writable, fsync-safe volume","Snapshot the acme_server folder alongside regular config backups"],"tags":["pki","acme","bbolt","database","filesystem"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}