cube-js/cube · error

CacheStore cannot be used on the worker node! queue_add_and_

Error message

CacheStore cannot be used on the worker node! queue_add_and_retrieve was used.

What it means

queue_add_and_retrieve atomically enqueues work and fetches results; it is a metastore-only queue operation. CacheStore (worker node store) panics on any invocation because workers hold no queue state.

Source

Thrown at rust/cubestore/cubestore/src/cachestore/cache_rocksstore.rs:2003

        &self,
        _limit: Option<usize>,
    ) -> Result<Vec<IdRow<QueueResult>>, CubeError> {
        panic!("CacheStore cannot be used on the worker node! queue_results_all was used.")
    }

    async fn queue_results_multi_delete(&self, _ids: Vec<u64>) -> Result<(), CubeError> {
        panic!("CacheStore cannot be used on the worker node! queue_results_multi_delete was used.")
    }

    async fn queue_add(&self, _payload: QueueAddPayload) -> Result<QueueAddResponse, CubeError> {
        panic!("CacheStore cannot be used on the worker node! queue_add was used.")
    }

    async fn queue_add_and_retrieve(
        &self,
        _payload: QueueAddAndRetrievePayload,
    ) -> Result<QueueAddAndRetrieveResponse, CubeError> {
        panic!("CacheStore cannot be used on the worker node! queue_add_and_retrieve was used.")
    }

    async fn queue_clear(&self) -> Result<(), CubeError> {
        panic!("CacheStore cannot be used on the worker node! queue_clear was used.")
    }

    async fn queue_to_cancel(
        &self,
        _prefix: String,
        _orphaned_timeout: Option<u32>,
        _heartbeat_timeout: Option<u32>,
    ) -> Result<Vec<IdRow<QueueItem>>, CubeError> {
        panic!("CacheStore cannot be used on the worker node! queue_to_cancel was used.")
    }

    async fn queue_list(
        &self,
        _prefix: String,

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Route add-and-retrieve calls to the metastore node.
  2. Review connection setup so the queue-capable client targets the metastore, not the worker pool.
  3. Ensure the node executing this call was started with metastore storage enabled.
  4. Add a role check before issuing queue calls in custom tooling.

Example fix

// before
let resp = workerStore.queueAddAndRetrieve(payload).await?;
// after
let resp = metastoreStore.queueAddAndRetrieve(payload).await?;
Defensive patterns

Strategy: validation

Validate before calling

if !is_metastore(store.node()) {
    return Err(CubeError::internal("queue_add_and_retrieve requires the metastore node"));
}
let resp = store.queueAddAndRetrieve(payload).await?;

Type guard

fn is_metastore(node: &CubeStoreNode) -> bool {
    matches!(node.role(), NodeRole::Metastore)
}

Prevention

When it happens

Trigger: Calling queue_add_and_retrieve (QueueAddAndRetrievePayload) against a worker node — typically from query orchestration code resolving the CubeStore connection to a worker.

Common situations: Multi-node deployments where pre-aggregation build requests are balanced across all nodes; miswired client connection strings after adding worker nodes.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/4c120f5e1c5eedb4. Report an issue: GitHub.