usememos/memos · critical

dsn required

Error message

dsn required

What it means

The SQLite driver refuses to open when profile.DSN is empty, before registering custom functions or connecting. Unlike MySQL/Postgres it has no default file path at this layer, so an empty DSN is treated as misconfiguration rather than silently creating a database in an unintended location.

Source

Thrown at store/db/sqlite/sqlite.go:27

	// Note: modernc.org/sqlite driver is imported in functions.go where
	// RegisterScalarFunction is used. No blank import needed here.

	"github.com/usememos/memos/internal/profile"
	"github.com/usememos/memos/store"
)

type DB struct {
	db      *sql.DB
	profile *profile.Profile
}

// NewDB opens a database specified by its database driver name and a
// driver-specific data source name, usually consisting of at least a
// database name and connection information.
func NewDB(profile *profile.Profile) (store.Driver, error) {
	// Ensure a DSN is set before attempting to open the database.
	if profile.DSN == "" {
		return nil, errors.New("dsn required")
	}

	if err := ensureUnicodeLowerRegistered(); err != nil {
		return nil, errors.Wrap(err, "failed to register sqlite unicode lower function")
	}

	if err := ensureRegexpRegistered(); err != nil {
		return nil, errors.Wrap(err, "failed to register sqlite regexp function")
	}

	// Connect to the database with some sane settings:
	// - No shared-cache: it's obsolete; WAL journal mode is a better solution.
	// - No foreign key constraints: it's currently disabled by default, but it's a
	// good practice to be explicit and prevent future surprises on SQLite upgrades.
	// - Journal mode set to WAL: it's the recommended journal mode for most applications
	// as it prevents locking issues.
	// - mmap size set to 0: it disables memory mapping, which can cause OOM errors on some systems.
	//

View on GitHub (pinned to 14d757ce1f)

Solutions

  1. Set the DSN to a writable file path, e.g. MEMOS_DSN=/var/opt/memos/memos_prod.db or pass --data
  2. Verify the parent directory exists and the process user can write it
  3. Check env var spelling if you expected a DSN to be set

Example fix

# before
docker run usememos/memos --driver sqlite
# after
docker run -v memos_data:/var/opt/memos usememos/memos --driver sqlite --data /var/opt/memos/memos_prod.db
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(dsn) == "" {
    log.Fatal("sqlite driver requires a DSN file path, e.g. --data /var/opt/memos/memos_prod.db")
}

Type guard

func hasSQLiteDSN(dsn string) bool { return strings.TrimSpace(dsn) != "" }

Prevention

When it happens

Trigger: Running memos with --driver sqlite but no --data/-d DSN and no MEMOS_DSN env var; env var name typos; container deployments that forgot to mount/set the data path.

Common situations: Docker runs missing the volume or env wiring; CLI scripts that conditionally set DSN but skip the sqlite branch; CI configs that only populate the Postgres DSN.

Related errors


AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15). Data as JSON: /api/errors/28e45ac48a55dbf9. Report an issue: GitHub.