linera-io/linera-protocol · error · anyhow

Query "{}" failed after {} retries.

Error message

Query "{}" failed after {} retries.

What it means

`query_node` POSTs a GraphQL query to the node service and inspects the JSON body: a top-level `errors` field makes it log the errors and retry; a transport timeout also retries; only a clean response with `data` returns. After `n_try` exhausted attempts it bails with the truncated query text and the attempt count. Each failed attempt logs a warn with the GraphQL errors, so the bail is the aggregate of a consistently failing query.

Source

Thrown at linera-service/src/cli_wrappers/wallet.rs:1959

                "Query \"{}\" failed: {}",
                truncate_query_output(query),
                response
                    .text()
                    .await
                    .unwrap_or_else(|error| format!("Could not get response text: {error}"))
            );
            let value: Value = response.json().await.context("invalid JSON")?;
            if let Some(errors) = value.get("errors") {
                tracing::warn!(
                    "Query \"{}\" failed: {}",
                    truncate_query_output(query),
                    errors
                );
            } else {
                return Ok(value["data"].clone());
            }
        }
        bail!(
            "Query \"{}\" failed after {} retries.",
            truncate_query_output(query),
            n_try
        );
    }

    /// Creates an application from a published module via the `createApplication` mutation.
    pub async fn create_application<
        Abi: ContractAbi,
        Parameters: Serialize,
        InstantiationArgument: Serialize,
    >(
        &self,
        chain_id: &ChainId,
        module_id: &ModuleId<Abi, Parameters, InstantiationArgument>,
        parameters: &Parameters,
        argument: &InstantiationArgument,
        required_application_ids: &[ApplicationId],

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Check the warn logs — each attempt logs the exact GraphQL errors the service returned
  2. Verify the query itself: chain ID format, field names, and that the service tracks the chain
  3. Ensure the node service has started and finished critical syncing before issuing queries
  4. Retry after the service recovers, or call query_node with a higher retry count if the API allows it
Defensive patterns

Strategy: retry

Validate before calling

// Only issue queries the service can answer: chain must be tracked.
if !client.query_applications_list().await?.iter().any(/* ... */) {
    // wait for service readiness instead of burning all retries
    tokio::time::sleep(Duration::from_secs(1)).await;
}

Try / catch

match client.query_node(query).await {
    Err(e) if e.to_string().contains("failed after") => {
        // retries already exhausted: the query itself is likely wrong,
        // check the per-attempt GraphQL errors in the warn logs before retrying
        log::error!("query permanently failed: {e}");
        return Err(e);
    }
    result => result,
}

Prevention

When it happens

Trigger: Every attempt returns GraphQL errors — querying a chain the service does not track, unknown/misnamed fields, unauthorized subscriptions — or every attempt times out against an overloaded or dead service.

Common situations: Integration tests racing ahead of chain/application creation; node service still syncing after startup; schema changes between wrapper and service versions; service starved under load so reqwest times out repeatedly.

Related errors


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