Skip to content

startup: Internal wallets have transient invalid passphrase error. #3574

@JoeGruffins

Description

@JoeGruffins

Seen a few times with v1.1.0-rc1 on linux arm64 (raspberry pi) but is a transient problem. Was not noticed on v1.0.6 I don't think. May be specific to the platform. The affected wallet will be unusable until restart.

Native Wallet Startup/Unlock Failures

Summary

Native wallets (DCR and BTC) intermittently fail during startup with
"invalid passphrase" errors. The failures resolve after one or more
restarts. Observed on both DCR (unlock phase) and BTC (connect phase).

DCR Error (unlock phase)

[ERR] CORE: notify: |ERROR| (feepayment) Wallet unlock error - Connected to
wallet to complete registration at dex.decred.org:7232, but failed to unlock:
error upgrading accounts: cannot unlock wallet to check mixing accts:
wallet.Unlock: invalid passphrase: secretkey.DeriveKey

BTC Error (connect phase)

[ERR] CORE: Unable to connect to btc wallet (start and sync wallets BEFORE
starting dex!): connectWallet: failed to connect btc wallet: ConnectOnce
error: connect failure: couldn't load wallet: invalid passphrase for master
public key
  • Failed on first two startups, succeeded on third
  • BTC native SPV wallet (password derived from app seed)

Environment

  • Platform: Linux arm64
  • v1.1.0-rc1 client
  • Both wallets use internal (native SPV) with app-seed-derived passwords

DCR Reproduction Context

  • Wallet was working fine on master, error appeared on current build
  • Mixing is NOT enabled
  • Wallet synced ~10 seconds after the failed unlock attempt
  • Manual unlock from wallets page also failed with same error
  • Only resolved after full app restart
  • The error path goes through "check mixing accts" even though mixing
    is not enabled

Code Path

  1. Login calls connectWallets(crypter) - connects DCR wallet but does
    NOT unlock it (unlock only happens if mixing is needed)
  2. Login calls initializeDEXConnections(crypter) which calls
    initializeDEXConnection
  3. At core.go:5487, bond target tier > 0, so it tries to prepare the
    bond wallet
  4. At core.go:5498, wallet is connected but not unlocked
  5. wallet.Unlock(crypter) at line 5499 decrypts encPW successfully
    (no decryption error), then passes the decrypted password to the DCR
    wallet backend
  6. DCR wallet Unlock (dcr.go:5012) calls upgradeAccounts
  7. upgradeAccounts (spv.go:953) calls ew.Unlock(ctx, pw, nil) on
    the underlying dcrwallet - this fails with "invalid passphrase"

Key Observations

  • The crypter.Decrypt(encPW) step succeeds (otherwise the error would
    be "decryption error", not "invalid passphrase")
  • The decrypted password is rejected by the underlying dcrwallet
  • The wallet had NOT finished syncing at the time of the unlock attempt
    (synced 10s later at 05:41:40)
  • Manual unlock also failed - only resolved after full app restart
  • The upgradeAccounts code path always tries to "check mixing accts"
    regardless of whether mixing is enabled (spv.go:953-967)
  • This may be a dcrwallet issue where the wallet enters a bad state
    that persists until the wallet DB is closed and reopened

Possible Causes

  1. Underlying wallet bad state: Both dcrwallet and btcwallet may
    enter a state where key derivation fails even with the correct
    password. This state persists across attempts within the same
    process but is cleared by closing and reopening the wallet DB
    (full app restart). The BTC case required two restarts, suggesting
    the bad state can survive a single restart occasionally.

  2. Wallet not ready: The SPV wallet may not be fully initialized when
    the key derivation is attempted. The wallet might behave differently
    before sync completes. The initial failure could poison the wallet
    state for subsequent attempts within the same process.

  3. upgradeAccounts always checks mixing (DCR-specific): The
    upgradeAccounts path (spv.go:953) unconditionally calls
    ew.Unlock and setupMixingAccounts even when mixing is not
    enabled. If dcrwallet has a bug in this path, it would affect all
    users regardless of mixing preference.

Potential Fixes

  • Investigate dcrwallet's secretkey.DeriveKey for conditions that
    cause it to reject a correct password (possibly pre-sync state)
  • Consider skipping upgradeAccounts/setupMixingAccounts when mixing
    is not enabled
  • Retry the bond wallet unlock after sync completes (there's already a
    Wallet synced for asset dcr event that could trigger this)
  • If the initial unlock fails, avoid poisoning the wallet state so
    subsequent manual unlocks can succeed without restart

Files

  • client/core/core.go:5486-5505 - bond wallet unlock in initializeDEXConnection
  • client/core/core.go:4900-4905 - Login order: connectWallets then initializeDEXConnections
  • client/asset/dcr/dcr.go:5012-5017 - Unlock -> upgradeAccounts
  • client/asset/dcr/spv.go:953-967 - upgradeAccounts -> ew.Unlock
  • client/core/wallet.go:104-139 - xcWallet.Unlock

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions