JuliusBrussee/caveman · error

budget is below CCR storage minimum

Error message

budget %d is below CCR storage minimum %d

What it means

configureStorageBudget enforces a CCR storage budget via SQLite PRAGMA max_page_count. This error is returned when the requested budget in bytes, divided by the database page size, yields fewer pages than minimumStoragePages (16), meaning the configured maxBytes is too small to be usable for the store.

Solutions

  1. Increase the configured storage budget to at least 16 pages (check PRAGMA page_size of the db; commonly >= 65536 bytes)
  2. Check the config/env value supplying maxBytes for unit mistakes (KB vs bytes)
  3. Let the library choose a default budget instead of passing an explicit tiny one
  4. Verify the actual minimum via the error message: minimumStoragePages*pageSize

Example fix

// before
store, err := ccr.Open(dbPath, ccr.WithMaxStorageBytes(1024)) // below minimum
// after
store, err := ccr.Open(dbPath, ccr.WithMaxStorageBytes(1<<20)) // 1 MiB
Defensive patterns

Strategy: validation

Validate before calling

const minBytes = 16 * 4096 // minimumStoragePages * page_size
func budgetOK(maxBytes int64) bool { return maxBytes >= minBytes }

Try / catch

if err := configureBudget(db, maxBytes); err != nil && strings.Contains(err.Error(), "below CCR storage minimum") {
    return fmt.Errorf("raise maxBytes to at least 16 pages: %w", err)
}

Prevention

When it happens

Trigger: Calling Open/openWithBudgetHooks with a very small maxBytes (less than 16 * page_size, typically 16*4096 = 64KB); a config file supplying e.g. maxStorageBytes: 1024; a miscomputed budget from environment variables or a downsized deployment config.

Common situations: Operator typo setting the budget in KB while the code expects bytes; aggressive disk-quota configuration for small containers; unit mismatch after migrating config from another tool.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/3355f5709bb400ba. Report an issue: GitHub.

Appendix: source

Thrown at engine/ccr/store_sqlite.go:386

		return err
	}
	if !os.SameFile(info, secured) {
		return fmt.Errorf("file changed while securing")
	}
	return nil
}

func configureStorageBudget(db *sql.DB, maxBytes int64) error {
	var pageSize int64
	if err := db.QueryRow(`PRAGMA page_size`).Scan(&pageSize); err != nil {
		return fmt.Errorf("read page size: %w", err)
	}
	if pageSize <= 0 {
		return errors.New("invalid sqlite page size")
	}
	maxPages := maxBytes / pageSize
	if maxPages < minimumStoragePages {
		return fmt.Errorf("budget %d is below CCR storage minimum %d", maxBytes, minimumStoragePages*pageSize)
	}
	var applied int64
	if err := db.QueryRow(fmt.Sprintf(`PRAGMA max_page_count=%d`, maxPages)).Scan(&applied); err != nil {
		return err
	}
	if applied < maxPages {
		maxPages = applied
	}
	autoCheckpoint := maxPages / 16
	if autoCheckpoint < 1 {
		autoCheckpoint = 1
	}
	if _, err := db.Exec(fmt.Sprintf(`PRAGMA wal_autocheckpoint=%d`, autoCheckpoint)); err != nil {
		return err
	}
	_, err := db.Exec(fmt.Sprintf(`PRAGMA journal_size_limit=%d`, maxBytes/8))
	return err
}

View on GitHub (pinned to 3ee70a1026)