Error 394: QUERY_WAS_CANCELLED
This error occurs when a query execution is explicitly cancelled or terminated before completion. It indicates that the query was stopped either by user request, system shutdown, resource limits, or automatic cancellation policies.
Most common causes
-
User-initiated cancellation
- User executed
KILL QUERYcommand - Client sent cancel request (Ctrl+C in clickhouse-client)
- Application cancelled query via API
- Query stopped through management interface
- User executed
-
Client disconnection
- Client connection closed before query completed
- HTTP client disconnected (with
cancel_http_readonly_queries_on_client_close = 1) - Network connection lost between client and server
- Client timeout causing connection termination
-
System shutdown or restart
- ClickHouse server shutting down gracefully
- Pod termination during Kubernetes rolling update
- Service restart draining active queries
- Graceful shutdown timeout reached (ClickHouse Cloud: 1 hour)
-
Query timeout enforcement
- Query exceeding
max_execution_timelimit - Timeout from
KILL QUERYcommand execution - Automatic cancellation due to resource policies
- Query exceeding
-
Resource protection mechanisms
- Query was cancelled due to memory pressure
- Too many concurrent queries, oldest cancelled
- System overload protection
- Emergency query termination
-
Distributed query cancellation
- Parent query cancelled, child queries on remote servers also cancelled
- One shard failing causes entire distributed query cancellation
- Replica unavailability during parallel replica execution
Common solutions
1. Check if cancellation was intentional
2. Identify who/what cancelled the query
3. Increase timeout limits if queries are legitimately long
4. Handle client disconnections
cancel_http_readonly_queries_on_client_close only works when readonly > 0 (automatic for HTTP GET requests).
5. Handle shutdowns gracefully
For applications that need to survive pod restarts:
6. Check for system resource issues
Common scenarios
Scenario 1: User killed query
Cause: User executed KILL QUERY WHERE query_id = 'xxx'.
Solution:
- This is expected behavior
- Query was intentionally stopped
- Check
system.query_logto see who killed it - No action needed unless kill was unintentional
Scenario 2: Client disconnection auto-cancel
Cause: Client disconnected and cancel_http_readonly_queries_on_client_close = 1.
Solution:
Scenario 3: Graceful shutdown during rolling update
Cause: ClickHouse Cloud pod shutting down during rolling update.
Solution:
- Implement retry logic in application
- Design queries to complete within grace period (< 1 hour for Cloud)
- For very long queries, use
INSERT INTO ... SELECTto materialize results - Monitor for scheduled maintenance windows
Scenario 4: Query takes too long to cancel
Cause: Known issue with some query types, especially those with subqueries or complex JOINs.
Solution:
- Query will eventually cancel (may take time to reach cancellation points)
- Consider using
KILL QUERY SYNCfor synchronous termination - For stuck queries, may need to restart ClickHouse (rare)
- Upgrade to newer versions with improved cancellation
Scenario 5: Cannot cancel query
Cause: Query stuck in operation that doesn't check cancellation flag.
Solution:
Prevention tips
- Set appropriate timeouts: Configure
max_execution_timefor workload patterns - Monitor long queries: Track and optimize slow queries before they need cancellation
- Handle shutdowns gracefully: Design applications to retry cancelled queries
- Use query result cache: Cache expensive query results to avoid re-execution
- Implement checkpointing: For very long operations, break into smaller steps
- Monitor cancellation patterns: Track why queries are being cancelled
- Configure client timeouts: Match client and server timeout settings
Debugging steps
-
Find recently cancelled queries:
-
Check for kill commands:
-
Check for pod restarts (ClickHouse Cloud):
-
Check error_log for cancellation patterns:
-
Analyze cancellation timing:
-
Check if queries complete before showing cancelled:
Special considerations
For HTTP interface:
- Setting
cancel_http_readonly_queries_on_client_close = 1auto-cancels on disconnect - Only works with
readonly > 0(automatic for GET requests) - Useful to prevent runaway queries from disconnected clients
- Can cause issues if the client has a short timeout but the query is valid
For distributed queries:
- Cancelling parent query cancels all child queries on remote servers
- Child queries show QUERY_WAS_CANCELLED when parent cancelled
- Check
initial_query_idto find the parent query
For long-running queries:
- Cancellation may take time to propagate through query pipeline
- Some operations (like large JOINs or subqueries) have limited cancellation points
- Query must reach a cancellation checkpoint to actually stop
- In rare cases, queries may appear "stuck" but are making progress to cancellation
For graceful shutdowns (ClickHouse Cloud):
- During rolling updates, pods wait up to 1 hour for queries to complete
- Queries running longer than grace period are cancelled
- New connections rejected during shutdown
- Design applications to handle these graceful cancellations
Cancellation vs interruption:
exception_code = 394: Query was cancelled (shows as error)exception_code = 0with early termination: Query interrupted but not error- Check
typefield inquery_logto distinguish
Cancellation commands
Kill specific query:
Check kill status:
Settings affecting cancellation
Distinguishing cancellation types
Known issues with cancellation
Issue 1: Slow query cancellation
- Symptom: Queries take a long time to cancel (minutes after
KILL QUERY) - Affected: Complex queries with subqueries or large JOINs
- Cause: Limited cancellation checkpoints in query execution
- Workaround: Use
KILL QUERY SYNCand wait, or restart server in extreme cases
Issue 2: Cannot cancel during subquery building
- Symptom: Query stuck building subquery, doesn't respond to cancel
- Affected: Queries with
INsubqueries or complex CTEs - Cause: Query planner doesn't check cancellation during subquery materialization
- Status: Known issue, improved in newer versions with new analyzer
Issue 3: Double cancellation error
- Symptom: "Cannot cancel. Either no query sent or already cancelled"
LOGICAL_ERROR - Affected: Distributed queries with failover
- Cause: Race condition in cancellation logic
- Impact: Usually harmless, query still gets cancelled
Best practices for handling cancellations
1. Implement retry logic:
2. Monitor cancellation patterns:
3. Design for graceful handling:
- Break very long operations into smaller chunks
- Use
INSERT INTO ... SELECTto materialize intermediate results - Implement savepoints for multi-stage operations
- Design applications to resume from last checkpoint
4. Configure appropriate timeouts:
Monitoring cancelled queries
When a query shows as cancelled but completed
Some queries may show QUERY_WAS_CANCELLED but actually completed:
This can happen when:
- Client disconnects after query completes but before receiving results
- Graceful shutdown starts after query finishes
- Race condition between completion and cancellation
Difference from query interruption
Preventing unwanted cancellations
-
Set appropriate limits:
-
Ensure stable client connections:
- Use persistent connections
- Configure TCP keep-alive
- Set appropriate client timeouts
- Handle network interruptions
-
Optimize query performance:
- Faster queries less likely to be cancelled
- Reduce execution time below timeout limits
- Use proper indexes and partitioning
-
Monitor system health:
- Track pod restarts and maintenance windows
- Alert on unexpected query cancellations
- Review cancellation patterns weekly
For ClickHouse Cloud users
Graceful shutdown behavior:
- Rolling updates happen automatically
- 1-hour grace period for running queries
- Queries >1 hour cancelled during restart
- New connections rejected during shutdown
- Design for <1 hour query duration or handle retries
Recommendations:
- Keep queries under 1 hour when possible
- Use materialized views for long aggregations
- Implement retry logic for
QUERY_WAS_CANCELLED - Monitor maintenance windows
- Break long operations into smaller chunks
If you're experiencing this error:
- Check if cancellation was intentional (
KILL QUERYor user action) - Review query duration vs configured timeouts
- Check for pod restarts or system shutdowns at error time
- Verify client didn't disconnect prematurely
- For unintentional cancellations, investigate what triggered them
- Implement retry logic if cancellations are transient
- Optimize queries if being cancelled due to timeout
- For queries that must run longer, increase timeout limits
- Monitor cancellation patterns to identify systemic issues
Related documentation: