"Error: attempt to write a readonly database" when trying to backup the SQLite DB #1012

Closed
opened 2026-02-04 23:37:36 +03:00 by OVERLORD · 1 comment
Owner

Originally created by @ThibaultNocchi on GitHub (Apr 22, 2021).

Subject of the issue

I've set up a cronjob to backup my SQLite DB as the documentation suggested.

But sometimes I can't read the DB and get the error "Error: attempt to write a readonly database" when trying a simple .tables command against it.

I've found that it happens when I reboot my system, and maybe when the app has been unaccessed for a while.
The reliable thing I found is when the DB is unavailable, there are no db.sqlite3-shm and db.sqlite3-wal files next to it. When they are present, I can read/write my DB via sqlite3.

The simple fix I found is logging in, then I guess a log session is wrote and the DB is "unlocked".

What can be done about it to be able to reliably access my DB?

PS: I've found #1404 but it doesn't seem to apply to my problem.

Deployment environment

Your environment (Generated via diagnostics page)

  • Bitwarden_rs version: v1.20.0
  • Web-vault version: v2.19.0
  • Running within Docker: true
  • Uses a reverse proxy: true
  • IP Header check: true (X-Real-IP)
  • Internet access: true
  • Internet access via a proxy: false
  • DNS Check: true
  • Time Check: true
  • Domain Configuration Check: false
  • HTTPS Check: false
  • Database type: SQLite
  • Database version: 3.33.0
  • Clients used:
  • Reverse proxy and version:
  • Other relevant information:

Config (Generated via diagnostics page)

{
  "_duo_akey": null,
  "_enable_duo": false,
  "_enable_email_2fa": false,
  "_enable_smtp": true,
  "_enable_yubico": true,
  "_ip_header_enabled": true,
  "admin_token": "***",
  "allowed_iframe_ancestors": "",
  "attachments_folder": "data/attachments",
  "authenticator_disable_time_drift": false,
  "data_folder": "data",
  "database_max_conns": 10,
  "database_url": "****/**.*******",
  "db_connection_retries": 15,
  "disable_2fa_remember": false,
  "disable_admin_token": false,
  "disable_icon_download": false,
  "domain": "****://*********",
  "domain_origin": "****://*********",
  "domain_path": "",
  "domain_set": false,
  "duo_host": null,
  "duo_ikey": null,
  "duo_skey": null,
  "email_attempts_limit": 3,
  "email_expiration_time": 600,
  "email_token_size": 6,
  "enable_db_wal": true,
  "extended_logging": true,
  "helo_name": null,
  "hibp_api_key": null,
  "icon_blacklist_non_global_ips": true,
  "icon_blacklist_regex": null,
  "icon_cache_folder": "data/icon_cache",
  "icon_cache_negttl": 259200,
  "icon_cache_ttl": 2592000,
  "icon_download_timeout": 10,
  "invitation_org_name": "Bitwarden_RS",
  "invitations_allowed": true,
  "ip_header": "X-Real-IP",
  "log_file": null,
  "log_level": "Info",
  "log_timestamp_format": "%Y-%m-%d %H:%M:%S.%3f",
  "org_attachment_limit": null,
  "org_creation_users": "",
  "password_iterations": 100000,
  "reload_templates": false,
  "require_device_email": false,
  "rsa_key_filename": "data/rsa_key",
  "sends_folder": "data/sends",
  "show_password_hint": true,
  "signups_allowed": true,
  "signups_domains_whitelist": "",
  "signups_verify": false,
  "signups_verify_resend_limit": 6,
  "signups_verify_resend_time": 3600,
  "smtp_accept_invalid_certs": false,
  "smtp_accept_invalid_hostnames": false,
  "smtp_auth_mechanism": null,
  "smtp_debug": false,
  "smtp_explicit_tls": false,
  "smtp_from": "",
  "smtp_from_name": "Bitwarden_RS",
  "smtp_host": null,
  "smtp_password": null,
  "smtp_port": 587,
  "smtp_ssl": true,
  "smtp_timeout": 15,
  "smtp_username": null,
  "templates_folder": "data/templates",
  "use_syslog": false,
  "user_attachment_limit": null,
  "web_vault_enabled": true,
  "web_vault_folder": "web-vault/",
  "websocket_address": "0.0.0.0",
  "websocket_enabled": true,
  "websocket_port": 3012,
  "yubico_client_id": null,
  "yubico_secret_key": null,
  "yubico_server": null
}

Expected behaviour

I'd like to be able to backup at any time.

Actual behaviour

I need to do operations on my app first (such as login) to be able to backup.

Thank you! :)

Originally created by @ThibaultNocchi on GitHub (Apr 22, 2021). ### Subject of the issue I've set up a cronjob to backup my SQLite DB as the documentation suggested. But sometimes I can't read the DB and get the error "Error: attempt to write a readonly database" when trying a simple `.tables` command against it. I've found that it happens when I reboot my system, and maybe when the app has been unaccessed for a while. The reliable thing I found is when the DB is unavailable, there are no `db.sqlite3-shm` and `db.sqlite3-wal` files next to it. When they are present, I can read/write my DB via `sqlite3`. The simple fix I found is logging in, then I guess a log session is wrote and the DB is "unlocked". What can be done about it to be able to reliably access my DB? PS: I've found #1404 but it doesn't seem to apply to my problem. ### Deployment environment ### Your environment (Generated via diagnostics page) * Bitwarden_rs version: v1.20.0 * Web-vault version: v2.19.0 * Running within Docker: true * Uses a reverse proxy: true * IP Header check: true (X-Real-IP) * Internet access: true * Internet access via a proxy: false * DNS Check: true * Time Check: true * Domain Configuration Check: false * HTTPS Check: false * Database type: SQLite * Database version: 3.33.0 * Clients used: * Reverse proxy and version: * Other relevant information: ### Config (Generated via diagnostics page) ```json { "_duo_akey": null, "_enable_duo": false, "_enable_email_2fa": false, "_enable_smtp": true, "_enable_yubico": true, "_ip_header_enabled": true, "admin_token": "***", "allowed_iframe_ancestors": "", "attachments_folder": "data/attachments", "authenticator_disable_time_drift": false, "data_folder": "data", "database_max_conns": 10, "database_url": "****/**.*******", "db_connection_retries": 15, "disable_2fa_remember": false, "disable_admin_token": false, "disable_icon_download": false, "domain": "****://*********", "domain_origin": "****://*********", "domain_path": "", "domain_set": false, "duo_host": null, "duo_ikey": null, "duo_skey": null, "email_attempts_limit": 3, "email_expiration_time": 600, "email_token_size": 6, "enable_db_wal": true, "extended_logging": true, "helo_name": null, "hibp_api_key": null, "icon_blacklist_non_global_ips": true, "icon_blacklist_regex": null, "icon_cache_folder": "data/icon_cache", "icon_cache_negttl": 259200, "icon_cache_ttl": 2592000, "icon_download_timeout": 10, "invitation_org_name": "Bitwarden_RS", "invitations_allowed": true, "ip_header": "X-Real-IP", "log_file": null, "log_level": "Info", "log_timestamp_format": "%Y-%m-%d %H:%M:%S.%3f", "org_attachment_limit": null, "org_creation_users": "", "password_iterations": 100000, "reload_templates": false, "require_device_email": false, "rsa_key_filename": "data/rsa_key", "sends_folder": "data/sends", "show_password_hint": true, "signups_allowed": true, "signups_domains_whitelist": "", "signups_verify": false, "signups_verify_resend_limit": 6, "signups_verify_resend_time": 3600, "smtp_accept_invalid_certs": false, "smtp_accept_invalid_hostnames": false, "smtp_auth_mechanism": null, "smtp_debug": false, "smtp_explicit_tls": false, "smtp_from": "", "smtp_from_name": "Bitwarden_RS", "smtp_host": null, "smtp_password": null, "smtp_port": 587, "smtp_ssl": true, "smtp_timeout": 15, "smtp_username": null, "templates_folder": "data/templates", "use_syslog": false, "user_attachment_limit": null, "web_vault_enabled": true, "web_vault_folder": "web-vault/", "websocket_address": "0.0.0.0", "websocket_enabled": true, "websocket_port": 3012, "yubico_client_id": null, "yubico_secret_key": null, "yubico_server": null } ``` ### Expected behaviour I'd like to be able to backup at any time. ### Actual behaviour I need to do operations on my app first (such as login) to be able to backup. Thank you! :)
Author
Owner

@BlackDex commented on GitHub (Apr 23, 2021):

I'm not sure what you are doing then, because using either .backup or VACUUM INTO will create a new file and only reads from the original. So, it should never attempt to write to the original db.sqlite3 file at all.

Be sure to check the correct syntax here: https://github.com/dani-garcia/bitwarden_rs/wiki/Backing-up-your-vault

Also, if you added it to a Linux cronjob, then make sure you escaped the % like \% signs within the crontab.

@BlackDex commented on GitHub (Apr 23, 2021): I'm not sure what you are doing then, because using either `.backup` or `VACUUM INTO` will create a new file and only reads from the original. So, it should never attempt to write to the original db.sqlite3 file at all. Be sure to check the correct syntax here: https://github.com/dani-garcia/bitwarden_rs/wiki/Backing-up-your-vault Also, if you added it to a Linux cronjob, then make sure you escaped the `%` like `\%` signs within the crontab.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/vaultwarden#1012