Skip to content

Commit ff34eeb

Browse files
committed
feat: add timeout handling for cache database operations
- Add 5-second timeout for BoltDB cache operations to prevent indefinite hangs - Return clearer error messages to help users identify lock conflicts - Update troubleshooting documentation with lock error guidance - Clarify that running multiple Trivy processes is not recommended
1 parent 3ada677 commit ff34eeb

File tree

4 files changed

+64
-11
lines changed

4 files changed

+64
-11
lines changed

docs/docs/references/troubleshooting.md

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,57 @@ $ trivy image --download-java-db-only
115115
$ trivy image [YOUR_JAVA_IMAGE]
116116
```
117117

118-
### Running in parallel takes same time as series run
119-
When running trivy on multiple images simultaneously, it will take same time as running trivy in series.
120-
This is because of a limitation of boltdb.
121-
> Bolt obtains a file lock on the data file so multiple processes cannot open the same database at the same time. Opening an already open Bolt database will cause it to hang until the other process closes it.
118+
### Database and cache lock errors
122119

123-
Reference : [boltdb: Opening a database][boltdb].
120+
!!! error
121+
```
122+
cache may be in use by another process
123+
```
124+
125+
!!! error
126+
```
127+
vulnerability database may be in use by another process
128+
```
129+
130+
By default, Trivy uses BoltDB for its vulnerability database and cache storage. BoltDB creates file locks to prevent data corruption, which means only one process can access the same database file at a time.
131+
132+
As stated in the BoltDB documentation:
133+
134+
> Please note that Bolt obtains a file lock on the data file so multiple processes cannot open the same database at the same time. Opening an already open Bolt database will cause it to hang until the other process closes it.
135+
136+
Reference: [BoltDB README](https://github.com/boltdb/bolt#opening-a-database)
137+
138+
These errors occur when:
139+
140+
- Multiple Trivy processes try to use the same cache directory simultaneously
141+
- A previous Trivy process did not shut down cleanly
142+
- Trivy server is running and holding locks on the database and cache
143+
144+
#### Important Note
145+
146+
Running multiple Trivy processes on the same machine is **not recommended**. Using the same cache directory for multiple processes does not improve performance and can cause unexpected errors due to BoltDB's locking mechanism.
147+
148+
#### Solutions
149+
150+
**Solution 1: Terminate conflicting processes** (Recommended)
151+
152+
Check for running Trivy processes and terminate them:
153+
154+
```bash
155+
$ ps aux | grep trivy
156+
$ kill [process_id]
157+
```
158+
159+
**Solution 2: Use different cache directories** (If multiple processes are absolutely necessary)
160+
161+
If you must run multiple Trivy processes on the same machine, specify different cache directories for each process:
162+
163+
```bash
164+
$ trivy image --cache-dir /tmp/trivy-cache-1 debian:11 &
165+
$ trivy image --cache-dir /tmp/trivy-cache-2 debian:12 &
166+
```
124167

125-
[boltdb]: https://github.com/boltdb/bolt#opening-a-database
168+
Note that each cache directory will download its own copy of the vulnerability database and other scan assets, which will increase network traffic and storage usage.
126169

127170
### Multiple Trivy servers
128171

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ require (
2424
github.com/aquasecurity/testdocker v0.0.0-20250616060700-ba6845ac6d17
2525
github.com/aquasecurity/tml v0.6.1
2626
github.com/aquasecurity/trivy-checks v1.11.3-0.20250604022615-9a7efa7c9169
27-
github.com/aquasecurity/trivy-db v0.0.0-20250716122853-45f09ec4df9c
27+
github.com/aquasecurity/trivy-db v0.0.0-20250731052236-c7c831e2254d
2828
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48
2929
github.com/aquasecurity/trivy-kubernetes v0.9.1
3030
github.com/aws/aws-sdk-go-v2 v1.36.6

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,8 @@ github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gw
829829
github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY=
830830
github.com/aquasecurity/trivy-checks v1.11.3-0.20250604022615-9a7efa7c9169 h1:TckzIxUX7lZaU9f2lNxCN0noYYP8fzmSQf6a4JdV83w=
831831
github.com/aquasecurity/trivy-checks v1.11.3-0.20250604022615-9a7efa7c9169/go.mod h1:nT69xgRcBD4NlHwTBpWMYirpK5/Zpl8M+XDOgmjMn2k=
832-
github.com/aquasecurity/trivy-db v0.0.0-20250716122853-45f09ec4df9c h1:nWJKidnaCx50H0JvqzCQNr0Ew9sUO0QcnGSeDJajmvc=
833-
github.com/aquasecurity/trivy-db v0.0.0-20250716122853-45f09ec4df9c/go.mod h1:upAJqDQkN5FdIJbtJMpokncGNhYAPGkpoCbaGciWPt4=
832+
github.com/aquasecurity/trivy-db v0.0.0-20250731052236-c7c831e2254d h1:Lc+p2CLARivVF48o7uRoFPaahNCvNFyBfeby0JqAMXo=
833+
github.com/aquasecurity/trivy-db v0.0.0-20250731052236-c7c831e2254d/go.mod h1:upAJqDQkN5FdIJbtJMpokncGNhYAPGkpoCbaGciWPt4=
834834
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI=
835835
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8=
836836
github.com/aquasecurity/trivy-kubernetes v0.9.1 h1:bSErQcavKXDh7XMwbGX7Vy//jR5+xhe/bOgfn9G+9lQ=

pkg/cache/fs.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package cache
22

33
import (
44
"encoding/json"
5+
"errors"
56
"os"
67
"path/filepath"
8+
"time"
79

810
"github.com/hashicorp/go-multierror"
911
bolt "go.etcd.io/bbolt"
@@ -12,6 +14,8 @@ import (
1214
"github.com/aquasecurity/trivy/pkg/fanal/types"
1315
)
1416

17+
const defaultFSCacheTimeout = 5 * time.Second
18+
1519
var _ Cache = &FSCache{}
1620

1721
type FSCache struct {
@@ -25,9 +29,15 @@ func NewFSCache(cacheDir string) (FSCache, error) {
2529
return FSCache{}, xerrors.Errorf("failed to create cache dir: %w", err)
2630
}
2731

28-
db, err := bolt.Open(filepath.Join(dir, "fanal.db"), 0o600, nil)
32+
db, err := bolt.Open(filepath.Join(dir, "fanal.db"), 0o600, &bolt.Options{
33+
Timeout: defaultFSCacheTimeout,
34+
})
2935
if err != nil {
30-
return FSCache{}, xerrors.Errorf("unable to open DB: %w", err)
36+
// Check if the error is due to timeout (database locked by another process)
37+
if errors.Is(err, bolt.ErrTimeout) {
38+
return FSCache{}, xerrors.Errorf("cache may be in use by another process: %w", err)
39+
}
40+
return FSCache{}, xerrors.Errorf("unable to open cache DB: %w", err)
3141
}
3242

3343
err = db.Update(func(tx *bolt.Tx) error {

0 commit comments

Comments
 (0)