linera-io/linera-protocol · critical · anyhow::Error

The chain with the ID returned by the faucet is not owned by

Error message

The chain with the ID returned by the faucet is not owned by you. Please make sure you are connecting to a genuine faucet.

What it means

During `linera wallet request-chain --faucet <URL>` the CLI generates a fresh key, asks the faucet for a chain via claim_to, then verifies the returned ChainDescription actually lists that key as an owner. If the faucet hands back a chain owned by someone else, this check fails — the classic signature of a fake or man-in-the-middle faucet.

Source

Thrown at linera-service/src/cli/main.rs:1832

            }) => {
                let start_time = Instant::now();
                let owner: AccountOwner = keystore.generate_key().await?.into();

                info!(
                    "Requesting a new chain for owner {owner} using the faucet at address \
                     {faucet_url}",
                );

                let destination = if fund_owner_account {
                    owner
                } else {
                    AccountOwner::CHAIN
                };
                let description = cli_wrappers::Faucet::new(faucet_url)
                    .claim_to(&owner, &destination)
                    .await?;

                ensure!(
                    description.config().ownership.is_owner(&owner),
                    "The chain with the ID returned by the faucet is not owned by you. \
                    Please make sure you are connecting to a genuine faucet."
                );

                wallet.insert(
                    description.id(),
                    &wallet::Chain {
                        owner: Some(owner),
                        ..(&description).into()
                    },
                )?;

                if set_default {
                    wallet.set_default_chain(description.id())?;
                }

                let context = options

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Verify the faucet URL against the network's official documentation (exact scheme, host, port)
  2. Re-run against a known-genuine faucet and never use the returned chain even if the command partially succeeded
  3. If you operate the faucet, check its genesis and chain-assignment logic: it must assign ownership to the requesting owner
  4. Treat repeat occurrences as a security incident: rotate keys and audit which endpoint produced them

Example fix

// before
let description = Faucet::new(faucet_url).claim_to(&owner, &destination).await?; // trust blindly

// after
let description = Faucet::new(faucet_url).claim_to(&owner, &destination).await?;
ensure!(
    description.config().ownership.is_owner(&owner),
    "faucet returned a chain we do not own -- do not use it"
);
Defensive patterns

Strategy: validation

Validate before calling

let description = Faucet::new(faucet_url).claim_to(&owner, &destination).await?;
if !description.config().ownership.is_owner(&owner) {
    anyhow::bail!("faucet returned a chain not owned by us -- refusing to import it");
}

Type guard

fn chain_owned_by(description: &ChainDescription, owner: &AccountOwner) -> bool {
    description.config().ownership.is_owner(owner)
}

Prevention

When it happens

Trigger: Running `linera wallet request-chain --faucet ...` (with or without fund-owner-account) where the faucet's claim_to response describes a chain whose ownership does not include the newly generated owner key.

Common situations: Typo-squatted or spoofed faucet URLs copied from tutorials; a MITM proxy rewriting responses; connecting a wallet to a faucet from a different network or genesis than intended.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/be2cf8fc7e5e9a05. Report an issue: GitHub.