{"record":{"id":"155dc506a319ddc3","repo":"apache/cassandra","slug":"attempted-to-serve-s-data-request-from-s-node-in","errorCode":null,"errorMessage":"Attempted to serve %s data request from %s node in %s","messagePattern":"Attempted to serve (.+?) data request from (.+?) node in (.+?)","errorType":"exception","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/ReadCommandVerbHandler.java","lineNumber":203,"sourceCode":"        {\n            Token token = ((SinglePartitionReadCommand)command).partitionKey().getToken();\n            Replica localReplica = getLocalReplica(metadata, token, command.metadata().keyspace);\n            if (localReplica == null)\n            {\n                metadata = ClusterMetadataService.instance().fetchLogFromPeerOrCMS(metadata, message.from(), message.epoch());\n                localReplica = getLocalReplica(metadata, token, command.metadata().keyspace);\n            }\n            if (localReplica == null)\n            {\n                StorageService.instance.incOutOfRangeOperationCount();\n                Keyspace.open(command.metadata().keyspace).metric.outOfRangeTokenReads.inc();\n                throw InvalidRoutingException.forTokenRead(message.from(), token, metadata.epoch, message.payload);\n            }\n\n            if (!command.acceptsTransient() && localReplica.isTransient())\n            {\n                MessagingService.instance().metrics.recordDroppedMessage(message, message.elapsedSinceCreated(NANOSECONDS), NANOSECONDS);\n                throw new InvalidRequestException(String.format(\"Attempted to serve %s data request from %s node in %s\",\n                                                                command.acceptsTransient() ? \"transient\" : \"full\",\n                                                                localReplica.isTransient() ? \"transient\" : \"full\",\n                                                                this));\n            }\n        }\n        else\n        {\n            AbstractBounds<PartitionPosition> range = ((PartitionRangeReadCommand) command).dataRange().keyRange();\n\n            // TODO: preexisting issue: for the range queries or queries that span multiple replicas, we can only make requests where the right token is owned, but not the left one\n            Replica maxTokenLocalReplica = getLocalReplica(metadata, range.right.getToken(), command.metadata().keyspace);\n            if (maxTokenLocalReplica == null)\n            {\n                metadata = ClusterMetadataService.instance().fetchLogFromPeerOrCMS(metadata, message.from(), message.epoch());\n                maxTokenLocalReplica = getLocalReplica(metadata, range.right.getToken(), command.metadata().keyspace);\n            }\n            if (maxTokenLocalReplica == null)\n            {","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/ReadCommandVerbHandler.java#L185-L221","documentation":"ReadCommandVerbHandler.checkTokenOwnership rejects a data request when the only local replica for the requested token is a transient replica but the read command requires full data (does not accept transient reads). Serving full reads from a transient replica would violate read consistency, so the message is dropped as invalid request.","triggerScenarios":"A coordinator routes a full (non-transient) read for a token to a node that only holds that range as a transient replica (e.g., RF lacks a full replica due to pending/decommissioning nodes), and doVerb -> checkTokenOwnership detects localReplica.isTransient().","commonSituations":"Cluster running with transient replication enabled while a node is still being bootstrapped or decommissioned; coordinator ring cache stale after topology change; misconfigured rack/DC leaving a range covered only by transient replicas.","solutions":["Fix replication so every range has enough full replicas (complete pending bootstrap/decommission, run repair)","Retry the read via a coordinator that routes to a full replica","Verify the coordinator's token map is current (restart or wait for gossip/metadata convergence)","If transient replication is not intended, ensure the read/command consistency and options do not rely on transient ranges"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before relying on reads on a node\nNodeToolOutput status = nodetool(\"info\");\nif (clusterHasPendingOrLeavingNodes(status)) {\n    // ranges may be served by transient replicas; finish topology ops first\n    throw new PreconditionFailed(\"complete bootstrap/decommission before reads\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Complete bootstrap/decommission and run repair before normal reads","Verify every range has the configured number of FULL replicas","Keep coordinator token maps current; avoid reading through freshly restarted coordinators until gossip settles","Monitor for transient-only ranges in your topology tooling"],"tags":["transient-replication","token-ownership","routing","invalid-request"],"backgroundTag":"invalid-argument-value","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}