{"record":{"id":"f432e99baf3de696","repo":"openzipkin/zipkin","slug":"remoteservice-remoteservice-unsupported-due-to-m","errorCode":null,"errorMessage":"remoteService={remoteService} unsupported due to missing table remote_service_by_service","messagePattern":"remoteService=(.+?) unsupported due to missing table remote_service_by_service","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"zipkin-storage/cassandra/src/main/java/zipkin2/storage/cassandra/CassandraSpanStore.java","lineNumber":199,"sourceCode":"    int endBucket = durationIndexBucket(timestampRange.endMillis * 1000);\n    if (startBucket > endBucket) {\n      throw new IllegalArgumentException(\n        \"Start bucket (\" + startBucket + \") > end bucket (\" + endBucket + \")\");\n    }\n\n    // \"\" isn't a real value. it is used to template bucketed calls and replaced later\n    String serviceName = null != request.serviceName() ? request.serviceName() : \"\";\n\n    // TODO: ideally, the buckets are traversed backwards, only spawning queries for older buckets\n    // if younger buckets are empty. This will be an async continuation, punted for now.\n    List<SelectTraceIdsFromServiceSpan.Input> serviceSpans = new ArrayList<>();\n    List<SelectTraceIdsFromServiceRemoteService.Input> serviceRemoteServices = new ArrayList<>();\n    String remoteService = request.remoteServiceName();\n    for (int bucket = endBucket; bucket >= startBucket; bucket--) {\n      boolean addSpanQuery = true;\n      if (remoteService != null) {\n        if (traceIdsFromServiceRemoteService == null) {\n          throw new IllegalArgumentException(\"remoteService=\" + remoteService\n            + \" unsupported due to missing table \" + TABLE_SERVICE_REMOTE_SERVICES);\n        }\n        serviceRemoteServices.add(\n          traceIdsFromServiceRemoteService.newInput(\n            serviceName,\n            remoteService,\n            bucket,\n            timestampRange,\n            traceIndexFetchSize));\n        // If the remote service query can satisfy the request, don't make a redundant span query\n        addSpanQuery = !spanName.isEmpty() || minDuration != null;\n      }\n      if (!addSpanQuery) continue;\n\n      serviceSpans.add(\n        traceIdsFromServiceSpan.newInput(\n          serviceName,\n          spanName,","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin-storage/cassandra/src/main/java/zipkin2/storage/cassandra/CassandraSpanStore.java#L181-L217","documentation":"CassandraSpanStore.newBucketedTraceIdCall throws IllegalArgumentException ('remoteService={remoteService} unsupported due to missing table remote_service_by_service') when a trace search filters by remote service name but the Cassandra schema does not have the remote_service_by_service table. That table was added in a later schema version; without it, remote-service filtering cannot be answered correctly and the query is rejected.","triggerScenarios":"QueryRequest.newBuilder().serviceName(...).remoteServiceName(...) executed against a keyspace on the older schema where the traceIdsFromServiceRemoteService factory (indexTtl-based table) is null.","commonSituations":"Reusing a legacy zipkin2 keyspace after upgrading the Zipkin server; querying with the Lens UI's remote-service filter against an unmigrated Cassandra cluster.","solutions":["Migrate to the current Cassandra schema (fresh keyspace zipkin3 or apply upgrade scripts) so remote_service_by_service exists","Set zipkin.storage.cassandra.keyspace to a keyspace created with the current schema","Until migrated, avoid remoteServiceName filters in queries"],"exampleFix":"# before\nzipkin.storage.cassandra.keyspace=zipkin2  # predates remote_service_by_service\n\n# after\nzipkin.storage.cassandra.keyspace=zipkin3\nzipkin.storage.cassandra.ensure-schema=true","handlingStrategy":"validation","validationCode":"// cqlsh check before enabling remote-service filters\n// DESCRIBE TABLE zipkin3.remote_service_by_service;  -- must succeed","typeGuard":null,"tryCatchPattern":"catch (IllegalArgumentException e) if message contains 'remote_service_by_service' -> retry the query without remoteServiceName and flag the schema as needing migration","preventionTips":["Migrate the Cassandra keyspace whenever upgrading Zipkin major versions","Gate remote-service search features on a schema-capability check"],"tags":["zipkin","cassandra","schema","remote-service","query"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}