{"record":{"id":"4d51457d68e5c9db","repo":"linera-io/linera-protocol","slug":"failed-to-start-faucet","errorCode":null,"errorMessage":"Failed to start faucet","messagePattern":"Failed to start faucet","errorType":"exception","errorClass":"anyhow","httpStatus":null,"severity":"error","filePath":"linera-service/src/cli_wrappers/wallet.rs","lineNumber":717,"sourceCode":"                \"--storage-path\".to_string(),\n                storage_path.to_string_lossy().to_string(),\n            ]);\n        if let Some(chain_id) = chain_id {\n            command.arg(chain_id.to_string());\n        }\n        let child = command.spawn_into()?;\n        let client = reqwest_client();\n        for i in 0..10 {\n            linera_base::time::timer::sleep(Duration::from_secs(i)).await;\n            let request = client.get(format!(\"http://localhost:{port}/\")).send().await;\n            if request.is_ok() {\n                tracing::info!(\"Faucet has started\");\n                return Ok(FaucetService::new(port, child, temp_dir));\n            } else {\n                tracing::debug!(\"Waiting for faucet to start\");\n            }\n        }\n        bail!(\"Failed to start faucet\");\n    }\n\n    /// Runs `linera local-balance`.\n    pub async fn local_balance(&self, account: Account) -> Result<Amount> {\n        let stdout = self\n            .command()\n            .await?\n            .arg(\"local-balance\")\n            .arg(account.to_string())\n            .spawn_and_wait_for_stdout()\n            .await?;\n        let amount = stdout\n            .trim()\n            .parse()\n            .context(\"error while parsing the result of `linera local-balance`\")?;\n        Ok(amount)\n    }\n","sourceCodeStart":699,"sourceCodeEnd":735,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-service/src/cli_wrappers/wallet.rs#L699-L735","documentation":"`run_faucet` spawns `linera faucet --port <p> --amount <a> --storage-path <tmp>/faucet_storage.sqlite [chain_id]` and polls `GET http://localhost:{port}/` up to 10 times with 0..9s sleeps. Any successful HTTP response counts as started; the bail means the faucet never answered — it crashed at startup or the port was unavailable. Heavy users include the e2e faucet/reconfiguration tests.","triggerScenarios":"The faucet child fails to bind its port (default 8080, commonly colliding with a node service), exits because the given chain/amount config is invalid, or comes up slower than the ~45s polling budget.","commonSituations":"Starting faucet and node service both on the default 8080 in the same test; the faucet's chain not yet synced/registered; leftover faucet process holding the port; slow CI machines.","solutions":["Give the faucet its own port (do not reuse the node-service port, especially the 8080 default)","Check for and kill stale listeners: `lsof -i :<port>`","Run `linera faucet --port <p> --amount <a>` manually with the same args to see its startup error","Ensure the faucet's chain exists and is funded before starting it, then retry"],"exampleFix":"// before\nlet service = client.run_node_service_with_options(Some(8080), ...).await?;\nlet faucet = client.run_faucet(None /* 8080 again! */, ...).await?; // port collision\n\n// after\nlet service = client.run_node_service_with_options(Some(18080), ...).await?;\nlet faucet = client.run_faucet(Some(18081), ...).await?;","handlingStrategy":"retry","validationCode":"// Never share the default 8080 between faucet and node service.\nlet faucet_port = linera_base::port::get_free_endpoint().await?.port().unwrap();\nlet faucet = client.run_faucet(Some(faucet_port), Some(chain_id), amount).await?;","typeGuard":null,"tryCatchPattern":"match client.run_faucet(Some(port), Some(chain_id), amount).await {\n    Err(e) if e.to_string() == \"Failed to start faucet\" => {\n        // child died or port busy; check lsof, verify the chain is funded/synced, retry\n        ensure_port_free(port)?;\n        client.run_faucet(Some(port), Some(chain_id), amount).await\n    }\n    result => result,\n}","preventionTips":["Assign the faucet a unique port; the default 8080 collides with node services in the same test","Ensure the faucet's chain is created and funded before spawning the faucet","Drop FaucetService handles in test teardown so children and their temp storage dirs are cleaned up"],"tags":["faucet","startup","port","cli-wrappers","integration-tests"],"backgroundTag":"service-startup-timeout","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}