Skip to content

Bitwarden Android Beta (2024.12.0 (19597)) fails to sync with SSH keys #5322

Description

@segln

Vaultwarden Support String

Your environment (Generated via diagnostics page)

EXPERIMENTAL_CLIENT_FEATURE_FLAGS=ssh-key-vault-item,ssh-agent

  • Vaultwarden version: v1.32.7
  • Web-vault version: v2024.6.2c
  • OS/Arch: linux/x86_64
  • Running within a container: true (Base: Debian)
  • Database type: PostgreSQL
  • Database version: PostgreSQL 16.3 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 14.2.1 20240805, 64-bit
  • Environment settings overridden!: 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
  • Browser/Server Time Check: true
  • Server/NTP Time Check: true
  • Domain Configuration Check: false
  • HTTPS Check: true
  • Websocket Check: true
  • HTTP Response Checks: true

Config & Details (Generated via diagnostics page)

Show Config & Details

Environment settings which are overridden: ADMIN_TOKEN

Config:

{
  "_duo_akey": null,
  "_enable_duo": false,
  "_enable_email_2fa": true,
  "_enable_smtp": true,
  "_enable_yubico": true,
  "_icon_service_csp": "",
  "_icon_service_url": "",
  "_ip_header_enabled": true,
  "_max_note_size": 10000,
  "_smtp_img_src": "***:",
  "admin_ratelimit_max_burst": 3,
  "admin_ratelimit_seconds": 300,
  "admin_session_lifetime": 20,
  "admin_token": "***",
  "allowed_connect_src": "",
  "allowed_iframe_ancestors": "",
  "attachments_folder": "data/attachments",
  "auth_request_purge_schedule": "30 * * * * *",
  "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_context_purge_schedule": "30 * * * * *",
  "duo_host": null,
  "duo_ikey": null,
  "duo_skey": null,
  "duo_use_iframe": false,
  "email_2fa_auto_fallback": false,
  "email_2fa_enforce_on_verified_invite": false,
  "email_attempts_limit": 3,
  "email_change_allowed": true,
  "email_expiration_time": 600,
  "email_token_size": 6,
  "emergency_access_allowed": true,
  "emergency_notification_reminder_schedule": "0 3 * * * *",
  "emergency_request_timeout_schedule": "0 7 * * * *",
  "enable_db_wal": true,
  "enable_websocket": true,
  "enforce_single_org_with_reset_pw_policy": false,
  "event_cleanup_schedule": "0 10 0 * * *",
  "events_days_retain": null,
  "experimental_client_feature_flags": "ssh-key-vault-item,ssh-agent",
  "extended_logging": true,
  "helo_name": null,
  "hibp_api_key": "***",
  "http_request_block_non_global_ips": true,
  "http_request_block_regex": 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,
  "icon_redirect_code": 302,
  "icon_service": "internal",
  "incomplete_2fa_schedule": "30 * * * * *",
  "incomplete_2fa_time_limit": 3,
  "increase_note_size_limit": false,
  "invitation_expiration_hours": 120,
  "invitation_org_name": "Vaultwarden",
  "invitations_allowed": false,
  "ip_header": "X-Real-IP",
  "job_poll_interval_ms": 30000,
  "log_file": null,
  "log_level": "warn",
  "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": "",
  "org_events_enabled": false,
  "org_groups_enabled": false,
  "password_hints_allowed": false,
  "password_iterations": 600000,
  "push_enabled": false,
  "push_identity_uri": "https://identity.bitwarden.com",
  "push_installation_id": "***",
  "push_installation_key": "***",
  "push_relay_uri": "https://push.bitwarden.com",
  "reload_templates": false,
  "require_device_email": false,
  "rsa_key_filename": "data/rsa_key",
  "send_purge_schedule": "0 5 * * * *",
  "sendmail_command": null,
  "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": null,
  "smtp_debug": false,
  "smtp_embed_images": true,
  "smtp_explicit_tls": null,
  "smtp_from": "*****************",
  "smtp_from_name": "Vaultwarden",
  "smtp_host": "********************",
  "smtp_password": "***",
  "smtp_port": 587,
  "smtp_security": "starttls",
  "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_sendmail": false,
  "use_syslog": false,
  "user_attachment_limit": null,
  "user_send_limit": null,
  "web_vault_enabled": true,
  "web_vault_folder": "web-vault/",
  "yubico_client_id": null,
  "yubico_secret_key": null,
  "yubico_server": null
}

Vaultwarden Build Version

v1.32.7

Deployment method

Official Container Image

Custom deployment method

No response

Reverse Proxy

nginx/1.27.2

Host/Server Operating System

Linux

Operating System Version

6.12.4-arch1-1 x86_64 GNU/Linux

Clients

Android

Client Version

Android Beta 2024.12.0 (19597)

Steps To Reproduce

  1. Sync the vault

Expected Result

Sync success

Actual Result

Sync failed

Logs

Bitwarden Android Beta: adb logcat log

The log reports Network Error: https://api.bitwarden.com/sync but I'm connecting to Vaultwarden so that can be ignored.

Details
12-23 18:54:56.815 32448 14626 W NetworkResultCall: Network Error: https://api.bitwarden.com/sync
12-23 18:54:56.816 32448 14626 W NetworkResultCall: kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 719619: Expected string literal but 'null' literal was found at path: $.ciphers[234].sshKey.keyFingerprint
12-23 18:54:56.816 32448 14626 W NetworkResultCall: Use 'coerceInputValues = true' in 'Json {}' builder to coerce nulls if property has a default value.
12-23 18:54:56.816 32448 14626 W NetworkResultCall: JSON input: .....ll,"sshKey":{"keyFingerprint":null,"privateKey":null,"public.....
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:24)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:32)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.AbstractJsonLexer.fail(AbstractJsonLexer.kt:580)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.AbstractJsonLexer.unexpectedToken(AbstractJsonLexer.kt:221)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.StringJsonLexer.consumeNextToken(StringJsonLexer.kt:76)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.StringJsonLexer.consumeKeyString(StringJsonLexer.kt:88)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.AbstractJsonLexer.consumeString(AbstractJsonLexer.kt:365)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeString(StreamingJsonDecoder.kt:339)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.encoding.AbstractDecoder.decodeStringElement(AbstractDecoder.kt:58)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson$Cipher$SshKey$$serializer.deserialize(SyncResponseJson.kt:736)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson$Cipher$SshKey$$serializer.deserialize(SyncResponseJson.kt:736)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.encoding.AbstractDecoder.decodeNullableSerializableElement(AbstractDecoder.kt:78)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson$Cipher$$serializer.deserialize(SyncResponseJson.kt:430)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson$Cipher$$serializer.deserialize(SyncResponseJson.kt:430)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.encoding.AbstractDecoder.decodeNullableSerializableElement(AbstractDecoder.kt:78)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson$$serializer.deserialize(SyncResponseJson.kt:26)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson$$serializer.deserialize(SyncResponseJson.kt:26)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at kotlinx.serialization.json.Json.decodeFromString(Json.kt:165)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at retrofit2.converter.kotlinx.serialization.Serializer$FromString.fromResponseBody(Serializer.kt:26)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at retrofit2.converter.kotlinx.serialization.DeserializationStrategyConverter.convert(DeserializationStrategyConverter.kt:11)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at retrofit2.converter.kotlinx.serialization.DeserializationStrategyConverter.convert(DeserializationStrategyConverter.kt:7)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:246)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:156)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
12-23 18:54:56.816 32448 14626 W NetworkResultCall: 	at java.lang.Thread.run(Thread.java:1012)

Screenshots or Videos

No response

Additional Context

Details

Bitwarden Android Beta requires ciphers.sshKey.keyFingerprint, but Vaultwarden's /api/sync does not return this property.

This bug does not occur if the SSH key is not in the vault.

Vaultwarden's SSH key feature works well with the Desktop client.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions