apache/skywalking · error · UnsupportedOperationException

Only BanyanDB storage support Trace V2 query now.

Error message

Only BanyanDB storage support Trace V2 query now.

What it means

TraceQueryService.queryTraces() is the Trace V2 (queryTraces GraphQL field) entry point. It is gated on supportTraceV2, which is set from whether the configured storage provider implements ITraceQueryV2DAO (only BanyanDB does). On any other storage (ES, H2, JDBC, BanyanDB-standalone excluded) it throws UnsupportedOperationException at query time — the server boots fine, so the failure appears only when a client calls the V2 API.

Source

Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/TraceQueryService.java:202

            }
        }
    }

    public TraceList queryTraces(final TraceQueryCondition condition) throws IOException {
        DebuggingTraceContext traceContext = TRACE_CONTEXT.get();
        DebuggingSpan span = null;
        try {
            if (traceContext != null) {
                StringBuilder msg = new StringBuilder();
                span = traceContext.createSpan("Query Service: queryTraces");
                msg.append("Condition: TraceQueryCondition: ").append(condition);
                span.setMsg(msg.toString());
            }
            getTraceQueryDAO();
            if (supportTraceV2) {
                return invokeQueryTraces(condition);
            } else {
                throw new UnsupportedOperationException("Only BanyanDB storage support Trace V2 query now.");
            }
        } finally {
            if (traceContext != null && span != null) {
                traceContext.stopSpan(span);
            }
        }
    }

    public boolean hasQueryTracesV2Support() {
        getTraceQueryDAO();
        return isSupportTraceV2();
    }

    private Trace invokeQueryTrace(final String traceId, @Nullable final Duration duration) throws IOException {
        Trace trace = new Trace();

        List<SegmentRecord> segmentRecords = getTraceQueryDAO().queryByTraceIdDebuggable(traceId, duration);
        if (segmentRecords.isEmpty()) {

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Switch OAP storage to BanyanDB (storage.selector: banyandb) if Trace V2 query is required, then restart.
  2. Or have the client use the V1 trace APIs (queryBasicTraces / queryTrace) which every storage implements; the UI typically falls back to them.
  3. Check hasQueryTracesV2Support() / GraphQL introspection before enabling V2 features in tooling.
  4. On mixed clusters, align all OAP nodes on the same storage selector.

Example fix

# application.yml — before
storage:
  selector: ${SW_STORAGE:elasticsearch}

# after
storage:
  selector: ${SW_STORAGE:banyandb}
  banyandb:
    targets: ${SW_STORAGE_BANYANDB_TARGETS:banyandb:17912}
Defensive patterns

Strategy: type-guard

Validate before calling

// Before enabling Trace V2 in a client
if (!traceQueryService.hasQueryTracesV2Support()) {
    // fall back to queryBasicTraces/queryTrace (V1)
}

Type guard

boolean traceV2Available = traceQueryService.hasQueryTracesV2Support(); // gate UI/API feature on this

Try / catch

try { TraceList t = traceQueryService.queryTraces(condition); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("BanyanDB")) { TraceBrief b = traceQueryService.queryBasicTraces(...); /* V1 fallback */ } else throw e; }

Prevention

When it happens

Trigger: GraphQL queryTraces(...) executed against an OAP whose storage selector is anything but BanyanDB; getTraceQueryDAO() resolved, supportTraceV2 is false, invokeQueryTraces is never reached.

Common situations: New UI versions calling queryTraces while the deployment still runs Elasticsearch storage; local dev with H2 memory storage; a cluster where some nodes were switched to BanyanDB and others not.

Related errors


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/29ef57e1cddd82bf. Report an issue: GitHub.