apache/shardingsphere · error · EmptyShardingRouteResultException

41

41

Error message

Can not get route result, please check your sharding rule configuration.

What it means

EmptyShardingRouteResultException is thrown by ShardingPrepareRouteContextChecker when a PREPARE/distributed-preparation statement finishes routing with zero route units. For prepared statements ShardingSphere requires at least one concrete route target; if the sharding conditions eliminate every data node (for example an always-false condition or a sharding key value that matches no actual node), the route result is empty and the statement is rejected with 'Can not get route result, please check your sharding rule configuration.'

Source

Thrown at features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/checker/ddl/ShardingPrepareRouteContextChecker.java:40

import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.context.RouteUnit;
import org.apache.shardingsphere.infra.session.query.QueryContext;
import org.apache.shardingsphere.sharding.exception.connection.EmptyShardingRouteResultException;
import org.apache.shardingsphere.sharding.exception.syntax.UnsupportedPrepareRouteToSameDataSourceException;
import org.apache.shardingsphere.sharding.route.engine.checker.ShardingRouteContextChecker;
import org.apache.shardingsphere.sharding.rule.ShardingRule;

import java.util.stream.Collectors;

/**
 * Sharding prepare route context checker.
 */
public final class ShardingPrepareRouteContextChecker implements ShardingRouteContextChecker {
    
    @Override
    public void check(final ShardingRule shardingRule, final QueryContext queryContext, final ShardingSphereDatabase database, final ConfigurationProperties props, final RouteContext routeContext) {
        if (routeContext.getRouteUnits().isEmpty()) {
            throw new EmptyShardingRouteResultException();
        }
        if (routeContext.getRouteUnits().stream().collect(Collectors.groupingBy(RouteUnit::getDataSourceMapper)).entrySet().stream().anyMatch(each -> each.getValue().size() > 1)) {
            throw new UnsupportedPrepareRouteToSameDataSourceException();
        }
    }
}

View on GitHub (pinned to e952770a21)

Solutions

  1. Check the sharding rule for the prepared statement's tables: confirm the sharding column, algorithm, and actualDataNodes actually cover the bound parameter values.
  2. Verify the PREPARE parameters: parameter markers must be bound before execution so sharding conditions can be derived; ensure you PREPARE with types/values the sharding algorithm supports.
  3. Test the equivalent SELECT/DELETE with literal values — if it also returns no route, the rule (not PREPARE) is the problem.
  4. If the table is not intended to be sharded, remove it from the sharding rule or use a default sharding strategy.

Example fix

-- before: value outside inline algorithm range
PREPARE p AS DELETE FROM t_order WHERE order_id = ?;
SET @id = 99999;  -- id % 4 is fine, but e.g. non-numeric binding fails routing

-- after: bind a value the sharding algorithm can evaluate
PREPARE p AS DELETE FROM t_order WHERE order_id = ?;
SET @id = 101;  -- order_id % 4 -> ds_1.t_order_1
EXECUTE p USING @id;
Defensive patterns

Strategy: validation

Validate before calling

// Before PREPARE, verify the sharding value maps to at least one actual data node
Object shardingValue = params[0];
Collection<DataNode> nodes = shardingRule.getShardingTable("t_order")
        .map(t -> t.getActualDataNodes()).orElse(Collections.emptyList());
if (nodes.isEmpty()) { throw new IllegalStateException("No actual data nodes for t_order"); }
// additionally smoke-test the literal form:
// SELECT 1 FROM t_order WHERE order_id = <literal> LIMIT 1

Try / catch

try {
    connection.prepareStatement("...", RETURN_GENERATED_KEYS);
} catch (final EmptyShardingRouteResultException ex) {
    // log sharding key + params; surface 'check sharding rule configuration' to operator
}

Prevention

When it happens

Trigger: A PREPARE statement whose RouteContext has no RouteUnits after routing: sharding key predicate matches no configured actual data node, a contradictory WHERE on the sharding column, or a rule/algorithm configuration that yields no mappings for the given sharding values.

Common situations: Using server-side PREPARE (or drivers that use it) with a sharding value outside the algorithm's range (e.g. inline expression ds_${id % 4} with a non-numeric or out-of-range value), or after editing sharding rules so the statement's tables no longer route anywhere.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/5970ebfd98f44e9e. Report an issue: GitHub.