Downloading attachments is normal, but uploading attachments prompts "An error occurred. IO" #1311

Closed
opened 2026-02-05 00:35:40 +03:00 by OVERLORD · 3 comments
Owner

Originally created by @aaro-n on GitHub (Jul 1, 2022).

Subject of the issue

Unable to add attachments, it prompts "An error occurred. IO"

Deployment environment

  • vaultwarden version:v1.25.0
  • Install method:Docker image

  • Clients used:web vault, desktop, Android

  • Reverse proxy and version:

  • MySQL/MariaDB or PostgreSQL version:

  • Other relevant details:
    It could be uploaded normally before, but it cannot be uploaded in the v1.25.0 version. (I can't remember which version can be uploaded. It has been uploaded successfully before, and now the attachment can be downloaded normally.)

Your environment (Generated via diagnostics page)

  • Vaultwarden version: v1.25.0
  • Web-vault version: v2.28.1
  • Running within Docker: true (Base: Alpine)
  • Environment settings overridden: false
  • 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: true
  • HTTPS Check: true
  • Database type: PostgreSQL
  • Database version: PostgreSQL 13.7 on x86_64-pc-linux-musl, compiled by gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219, 64-bit
  • Clients used:
  • Reverse proxy and version:
  • Other relevant information:

Config (Generated via diagnostics page)

Show Running Config

Environment settings which are overridden:

{
  "_duo_akey": null,
  "_enable_duo": false,
  "_enable_email_2fa": true,
  "_enable_smtp": true,
  "_enable_yubico": true,
  "_ip_header_enabled": true,
  "admin_ratelimit_max_burst": 3,
  "admin_ratelimit_seconds": 300,
  "admin_token": "***",
  "allowed_iframe_ancestors": "",
  "attachments_folder": "/attachments",
  "authenticator_disable_time_drift": false,
  "data_folder": "data",
  "database_conn_init": "",
  "database_max_conns": 10,
  "database_timeout": 30,
  "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": true,
  "duo_host": null,
  "duo_ikey": null,
  "duo_skey": null,
  "email_attempts_limit": 3,
  "email_expiration_time": 600,
  "email_token_size": 6,
  "emergency_access_allowed": true,
  "emergency_notification_reminder_schedule": "0 5 * * * *",
  "emergency_request_timeout_schedule": "0 5 * * * *",
  "enable_db_wal": false,
  "extended_logging": true,
  "helo_name": null,
  "hibp_api_key": null,
  "icon_blacklist_non_global_ips": true,
  "icon_blacklist_regex": null,
  "icon_cache_folder": "/icon_cache",
  "icon_cache_negttl": 259200,
  "icon_cache_ttl": 2592000,
  "icon_download_timeout": 10,
  "icon_redirect_code": 302,
  "icon_service": "internal",
  "incomplete_2fa_schedule": "30 * * * * *",
  "incomplete_2fa_time_limit": 3,
  "invitation_org_name": "Vaultwarden",
  "invitations_allowed": false,
  "ip_header": "X-Real-IP",
  "job_poll_interval_ms": 30000,
  "log_file": "/data/vaultwarden.log",
  "log_level": "Info",
  "log_timestamp_format": "%Y-%m-%d %H:%M:%S.%3f",
  "login_ratelimit_max_burst": 10,
  "login_ratelimit_seconds": 60,
  "org_attachment_limit": null,
  "org_creation_users": "",
  "password_iterations": 100000,
  "reload_templates": false,
  "require_device_email": false,
  "rsa_key_filename": "data/rsa_key",
  "send_purge_schedule": "0 5 * * * *",
  "sends_allowed": true,
  "sends_folder": "data/sends",
  "show_password_hint": false,
  "signups_allowed": false,
  "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": "\"Plain\"",
  "smtp_debug": false,
  "smtp_explicit_tls": true,
  "smtp_from": "*********@***.*******.****",
  "smtp_from_name": "密码服务",
  "smtp_host": "****.*******.***",
  "smtp_password": "***",
  "smtp_port": 465,
  "smtp_security": "force_tls",
  "smtp_ssl": null,
  "smtp_timeout": 15,
  "smtp_username": "*********@***.*******.****",
  "templates_folder": "data/templates",
  "tmp_folder": "data/tmp",
  "trash_auto_delete_days": null,
  "trash_purge_schedule": "0 5 0 * * *",
  "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
}

Steps to reproduce

Find a password item, add an attachment, and click save when prompted "An error occurred. IO"

Expected behaviour

Attachment uploaded successfully

Actual behaviour

An error occurred.IO

Troubleshooting data

a log:

[2022-07-01 14:16:56.696][start][INFO] Rocket has launched from http://0.0.0.0:80
[2022-07-01 14:16:56.697][parity_ws][INFO] Listening for new connections on 0.0.0.0:3012.
[2022-07-01 14:18:49.052][request][INFO] POST /identity/connect/token
[2022-07-01 14:18:49.066][response][INFO] (login) POST /identity/connect/token => 200 OK
[2022-07-01 14:18:49.311][request][INFO] GET /api/sync?excludeDomains=true
[2022-07-01 14:18:49.385][response][INFO] (sync) GET /api/sync?<data..> => 200 OK
[2022-07-01 14:18:55.465][parity_ws::io][INFO] Accepted a new tcp connection from 104.224.177.224:37620.
[2022-07-01 14:18:56.573][parity_ws::io][INFO] Accepted a new tcp connection from 104.224.177.224:37622.
[2022-07-01 14:18:57.101][request][INFO] GET /api/accounts/revision-date
[2022-07-01 14:18:57.103][response][INFO] (revision_date) GET /api/accounts/revision-date => 200 OK
[2022-07-01 14:18:57.534][request][INFO] POST /identity/connect/token
[2022-07-01 14:18:57.540][response][INFO] (login) POST /identity/connect/token => 200 OK
[2022-07-01 14:18:57.956][request][INFO] GET /api/sync
[2022-07-01 14:18:58.014][response][INFO] (sync) GET /api/sync?<data..> => 200 OK
[2022-07-01 14:19:07.664][request][INFO] POST /api/ciphers/33bc62f6-0171-4114-aea2-e4b5954d4fa2/attachment/v2
[2022-07-01 14:19:07.676][response][INFO] (post_attachment_v2) POST /api/ciphers/<uuid>/attachment/v2 => 200 OK
[2022-07-01 14:19:08.525][request][INFO] POST /api/ciphers/33bc62f6-0171-4114-aea2-e4b5954d4fa2/attachment/af8dad47ef1c58df4d76
[2022-07-01 14:19:08.648][error][ERROR] Io.
[CAUSE] Os {
    code: 18,
    kind: CrossesDevices,
    message: "Cross-device link",
}
[2022-07-01 14:19:08.648][response][INFO] (post_attachment_v2_data) POST /api/ciphers/<uuid>/attachment/<attachment_id> multipart/form-data => 400 Bad Request
[2022-07-01 14:19:09.081][request][INFO] DELETE /api/ciphers/33bc62f6-0171-4114-aea2-e4b5954d4fa2/attachment/af8dad47ef1c58df4d76
[2022-07-01 14:19:09.089][response][INFO] (delete_attachment) DELETE /api/ciphers/<uuid>/attachment/<attachment_id> => 200 OK
截屏2022-07-01 下午1 42 12
Originally created by @aaro-n on GitHub (Jul 1, 2022). <!-- # ### NOTE: Please update to the latest version of vaultwarden before reporting an issue! This saves you and us a lot of time and troubleshooting. See: * https://github.com/dani-garcia/vaultwarden/issues/1180 * https://github.com/dani-garcia/vaultwarden/wiki/Updating-the-vaultwarden-image # ### --> <!-- Please fill out the following template to make solving your problem easier and faster for us. This is only a guideline. If you think that parts are unnecessary for your issue, feel free to remove them. Remember to hide/redact personal or confidential information, such as passwords, IP addresses, and DNS names as appropriate. --> ### Subject of the issue <!-- Describe your issue here. --> Unable to add attachments, it prompts "An error occurred. IO" ### Deployment environment <!-- ========================================================================================= Preferably, use the `Generate Support String` button on the admin page's Diagnostics tab. That will auto-generate most of the info requested in this section. ========================================================================================= --> <!-- The version number, obtained from the logs (at startup) or the admin diagnostics page --> <!-- This is NOT the version number shown on the web vault, which is versioned separately from vaultwarden --> <!-- Remember to check if your issue exists on the latest version first! --> * vaultwarden version:v1.25.0 <!-- How the server was installed: Docker image, OS package, built from source, etc. --> * Install method:Docker image * Clients used:web vault, desktop, Android <!-- web vault, desktop, Android, iOS, etc. (if applicable) --> * Reverse proxy and version: <!-- if applicable --> * MySQL/MariaDB or PostgreSQL version: <!-- if applicable --> * Other relevant details: It could be uploaded normally before, but it cannot be uploaded in the v1.25.0 version. (I can't remember which version can be uploaded. It has been uploaded successfully before, and now the attachment can be downloaded normally.) ### Your environment (Generated via diagnostics page) * Vaultwarden version: v1.25.0 * Web-vault version: v2.28.1 * Running within Docker: true (Base: Alpine) * Environment settings overridden: false * 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: true * HTTPS Check: true * Database type: PostgreSQL * Database version: PostgreSQL 13.7 on x86_64-pc-linux-musl, compiled by gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219, 64-bit * Clients used: * Reverse proxy and version: * Other relevant information: ### Config (Generated via diagnostics page) <details><summary>Show Running Config</summary> **Environment settings which are overridden:** ```json { "_duo_akey": null, "_enable_duo": false, "_enable_email_2fa": true, "_enable_smtp": true, "_enable_yubico": true, "_ip_header_enabled": true, "admin_ratelimit_max_burst": 3, "admin_ratelimit_seconds": 300, "admin_token": "***", "allowed_iframe_ancestors": "", "attachments_folder": "/attachments", "authenticator_disable_time_drift": false, "data_folder": "data", "database_conn_init": "", "database_max_conns": 10, "database_timeout": 30, "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": true, "duo_host": null, "duo_ikey": null, "duo_skey": null, "email_attempts_limit": 3, "email_expiration_time": 600, "email_token_size": 6, "emergency_access_allowed": true, "emergency_notification_reminder_schedule": "0 5 * * * *", "emergency_request_timeout_schedule": "0 5 * * * *", "enable_db_wal": false, "extended_logging": true, "helo_name": null, "hibp_api_key": null, "icon_blacklist_non_global_ips": true, "icon_blacklist_regex": null, "icon_cache_folder": "/icon_cache", "icon_cache_negttl": 259200, "icon_cache_ttl": 2592000, "icon_download_timeout": 10, "icon_redirect_code": 302, "icon_service": "internal", "incomplete_2fa_schedule": "30 * * * * *", "incomplete_2fa_time_limit": 3, "invitation_org_name": "Vaultwarden", "invitations_allowed": false, "ip_header": "X-Real-IP", "job_poll_interval_ms": 30000, "log_file": "/data/vaultwarden.log", "log_level": "Info", "log_timestamp_format": "%Y-%m-%d %H:%M:%S.%3f", "login_ratelimit_max_burst": 10, "login_ratelimit_seconds": 60, "org_attachment_limit": null, "org_creation_users": "", "password_iterations": 100000, "reload_templates": false, "require_device_email": false, "rsa_key_filename": "data/rsa_key", "send_purge_schedule": "0 5 * * * *", "sends_allowed": true, "sends_folder": "data/sends", "show_password_hint": false, "signups_allowed": false, "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": "\"Plain\"", "smtp_debug": false, "smtp_explicit_tls": true, "smtp_from": "*********@***.*******.****", "smtp_from_name": "密码服务", "smtp_host": "****.*******.***", "smtp_password": "***", "smtp_port": 465, "smtp_security": "force_tls", "smtp_ssl": null, "smtp_timeout": 15, "smtp_username": "*********@***.*******.****", "templates_folder": "data/templates", "tmp_folder": "data/tmp", "trash_auto_delete_days": null, "trash_purge_schedule": "0 5 0 * * *", "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 } ``` </details> ### Steps to reproduce <!-- Tell us how to reproduce this issue. What parameters did you set (differently from the defaults) and how did you start vaultwarden? --> Find a password item, add an attachment, and click save when prompted "An error occurred. IO" ### Expected behaviour <!-- Tell us what you expected to happen --> Attachment uploaded successfully ### Actual behaviour <!-- Tell us what actually happened --> An error occurred.IO ### Troubleshooting data <!-- Share any log files, screenshots, or other relevant troubleshooting data --> a log: ``` [2022-07-01 14:16:56.696][start][INFO] Rocket has launched from http://0.0.0.0:80 [2022-07-01 14:16:56.697][parity_ws][INFO] Listening for new connections on 0.0.0.0:3012. [2022-07-01 14:18:49.052][request][INFO] POST /identity/connect/token [2022-07-01 14:18:49.066][response][INFO] (login) POST /identity/connect/token => 200 OK [2022-07-01 14:18:49.311][request][INFO] GET /api/sync?excludeDomains=true [2022-07-01 14:18:49.385][response][INFO] (sync) GET /api/sync?<data..> => 200 OK [2022-07-01 14:18:55.465][parity_ws::io][INFO] Accepted a new tcp connection from 104.224.177.224:37620. [2022-07-01 14:18:56.573][parity_ws::io][INFO] Accepted a new tcp connection from 104.224.177.224:37622. [2022-07-01 14:18:57.101][request][INFO] GET /api/accounts/revision-date [2022-07-01 14:18:57.103][response][INFO] (revision_date) GET /api/accounts/revision-date => 200 OK [2022-07-01 14:18:57.534][request][INFO] POST /identity/connect/token [2022-07-01 14:18:57.540][response][INFO] (login) POST /identity/connect/token => 200 OK [2022-07-01 14:18:57.956][request][INFO] GET /api/sync [2022-07-01 14:18:58.014][response][INFO] (sync) GET /api/sync?<data..> => 200 OK [2022-07-01 14:19:07.664][request][INFO] POST /api/ciphers/33bc62f6-0171-4114-aea2-e4b5954d4fa2/attachment/v2 [2022-07-01 14:19:07.676][response][INFO] (post_attachment_v2) POST /api/ciphers/<uuid>/attachment/v2 => 200 OK [2022-07-01 14:19:08.525][request][INFO] POST /api/ciphers/33bc62f6-0171-4114-aea2-e4b5954d4fa2/attachment/af8dad47ef1c58df4d76 [2022-07-01 14:19:08.648][error][ERROR] Io. [CAUSE] Os { code: 18, kind: CrossesDevices, message: "Cross-device link", } [2022-07-01 14:19:08.648][response][INFO] (post_attachment_v2_data) POST /api/ciphers/<uuid>/attachment/<attachment_id> multipart/form-data => 400 Bad Request [2022-07-01 14:19:09.081][request][INFO] DELETE /api/ciphers/33bc62f6-0171-4114-aea2-e4b5954d4fa2/attachment/af8dad47ef1c58df4d76 [2022-07-01 14:19:09.089][response][INFO] (delete_attachment) DELETE /api/ciphers/<uuid>/attachment/<attachment_id> => 200 OK ``` <img width="275" alt="截屏2022-07-01 下午1 42 12" src="https://user-images.githubusercontent.com/45537680/176836414-eba31319-8d8c-4c07-8305-2b1af7fdb04d.png">
Author
Owner

@dani-garcia commented on GitHub (Jul 1, 2022):

If you use a custom attachments_folder, you also need to set tmp_folder to the same filesystem, the files are first downloaded to the temp folder and then moved to the attachments folder, so if using separate filesystems the move will fail.

@dani-garcia commented on GitHub (Jul 1, 2022): If you use a custom `attachments_folder`, you also need to set `tmp_folder` to the same filesystem, the files are first downloaded to the temp folder and then moved to the attachments folder, so if using separate filesystems the move will fail.
Author
Owner

@aaro-n commented on GitHub (Jul 2, 2022):

According to what you said, the problem can be solved, but there are some other problems.

# docker-compose.yml
version: '3'

services:
 bitwarden:
  image: vaultwarden/server:alpine
  restart: always
  container_name: vaultwarden
  volumes:
    - ./bw-data:/data
#    - ./bw-attachments:/file/attachments
    - ./bw-icon:/icon_cache
#    - ./bw-tmp:/file/tmp
#    - ./bw-sends:/file/sends
  ports:
    - 820:80
    - 825:3012
  environment:
    - LOG_FILE=/data/vaultwarden.log
    - SIGNUPS_ALLOWED=false
    - INVITATIONS_ALLOWED=false
    - WEBSOCKET_ENABLED=true
#    - ATTACHMENTS_FOLDER=/file/attachments
    - ICON_CACHE_FOLDER=/icon_cache
#    - TMP_FOLDER=/file/tmp
#    - SENDS_FOLDER=/file/sends

Docker compose is configured in this way to upload attachments. The location of attachments in the container is: /data/attachments/, and the location of the entity host is: /home/www/vaultwarden/service/bw-data/attachments

# docker-compose.yml
version: '3'

services:
 bitwarden:
  image: vaultwarden/server:alpine
  restart: always
  container_name: vaultwarden
  volumes:
    - ./bw-data:/data
    - ./bw-attachments:/file/attachments
    - ./bw-icon:/icon_cache
    - ./bw-tmp:/file/tmp
    - ./bw-sends:/file/sends
  ports:
    - 820:80
    - 825:3012
  environment:
    - LOG_FILE=/data/vaultwarden.log
    - SIGNUPS_ALLOWED=false
    - INVITATIONS_ALLOWED=false
    - WEBSOCKET_ENABLED=true
    - ATTACHMENTS_FOLDER=/file/attachments
    - ICON_CACHE_FOLDER=/icon_cache
    - TMP_FOLDER=/file/tmp
    - SENDS_FOLDER=/file/sends

But if docker compose is configured like this, and uploading the attachment again, there will still be an "upload error. IO"

# docker-compose.yml
version: '3'

services:
 bitwarden:
  image: vaultwarden/server:alpine
  restart: always
  container_name: vaultwarden
  volumes:
    - ./bw-data:/data
    - ./bw-attachments:/file
    - ./bw-icon:/icon_cache
#    - ./bw-tmp:/file/tmp
#    - ./bw-sends:/file/sends
  ports:
    - 820:80
    - 825:3012
  environment:
    - LOG_FILE=/data/vaultwarden.log
    - SIGNUPS_ALLOWED=false
    - INVITATIONS_ALLOWED=false
    - WEBSOCKET_ENABLED=true
    - ATTACHMENTS_FOLDER=/file/attachments
    - ICON_CACHE_FOLDER=/icon_cache
    - TMP_FOLDER=/file/tmp
    - SENDS_FOLDER=/file/sends

This configuration can also upload attachments. To sum up, the container needs to map the parent directory. For example, attachments and temporary files are stored in /file/attachments and /file/tmp respectively, and docker needs to map /file

@aaro-n commented on GitHub (Jul 2, 2022): According to what you said, the problem can be solved, but there are some other problems. ``` # docker-compose.yml version: '3' services: bitwarden: image: vaultwarden/server:alpine restart: always container_name: vaultwarden volumes: - ./bw-data:/data # - ./bw-attachments:/file/attachments - ./bw-icon:/icon_cache # - ./bw-tmp:/file/tmp # - ./bw-sends:/file/sends ports: - 820:80 - 825:3012 environment: - LOG_FILE=/data/vaultwarden.log - SIGNUPS_ALLOWED=false - INVITATIONS_ALLOWED=false - WEBSOCKET_ENABLED=true # - ATTACHMENTS_FOLDER=/file/attachments - ICON_CACHE_FOLDER=/icon_cache # - TMP_FOLDER=/file/tmp # - SENDS_FOLDER=/file/sends ``` Docker compose is configured in this way to upload attachments. The location of attachments in the container is: /data/attachments/, and the location of the entity host is: /home/www/vaultwarden/service/bw-data/attachments ``` # docker-compose.yml version: '3' services: bitwarden: image: vaultwarden/server:alpine restart: always container_name: vaultwarden volumes: - ./bw-data:/data - ./bw-attachments:/file/attachments - ./bw-icon:/icon_cache - ./bw-tmp:/file/tmp - ./bw-sends:/file/sends ports: - 820:80 - 825:3012 environment: - LOG_FILE=/data/vaultwarden.log - SIGNUPS_ALLOWED=false - INVITATIONS_ALLOWED=false - WEBSOCKET_ENABLED=true - ATTACHMENTS_FOLDER=/file/attachments - ICON_CACHE_FOLDER=/icon_cache - TMP_FOLDER=/file/tmp - SENDS_FOLDER=/file/sends ``` But if docker compose is configured like this, and uploading the attachment again, there will still be an "upload error. IO" ``` # docker-compose.yml version: '3' services: bitwarden: image: vaultwarden/server:alpine restart: always container_name: vaultwarden volumes: - ./bw-data:/data - ./bw-attachments:/file - ./bw-icon:/icon_cache # - ./bw-tmp:/file/tmp # - ./bw-sends:/file/sends ports: - 820:80 - 825:3012 environment: - LOG_FILE=/data/vaultwarden.log - SIGNUPS_ALLOWED=false - INVITATIONS_ALLOWED=false - WEBSOCKET_ENABLED=true - ATTACHMENTS_FOLDER=/file/attachments - ICON_CACHE_FOLDER=/icon_cache - TMP_FOLDER=/file/tmp - SENDS_FOLDER=/file/sends ``` This configuration can also upload attachments. To sum up, the container needs to map the parent directory. For example, attachments and temporary files are stored in /file/attachments and /file/tmp respectively, and docker needs to map /file
Author
Owner

@aaro-n commented on GitHub (Jul 2, 2022):

The problem has been solved, please close this issue.

@aaro-n commented on GitHub (Jul 2, 2022): The problem has been solved, please close this issue.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/vaultwarden#1311