{"record":{"id":"c9b349b3535892bd","repo":"openzipkin/zipkin","slug":"endts-0-c9b349","errorCode":null,"errorMessage":"endTs <= 0","messagePattern":"endTs <= 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"zipkin/src/main/java/zipkin2/storage/QueryRequest.java","lineNumber":250,"sourceCode":"    }\n\n    /** Sets {@link QueryRequest#limit()} */\n    public Builder limit(int limit) {\n      this.limit = limit;\n      return this;\n    }\n\n    public QueryRequest build() {\n      // coerce service and span names to lowercase\n      if (serviceName != null) serviceName = serviceName.toLowerCase(Locale.ROOT);\n      if (remoteServiceName != null) remoteServiceName = remoteServiceName.toLowerCase(Locale.ROOT);\n      if (spanName != null) spanName = spanName.toLowerCase(Locale.ROOT);\n\n      if (\"\".equals(serviceName)) serviceName = null;\n      if (\"\".equals(remoteServiceName)) remoteServiceName = null;\n      if (\"\".equals(spanName) || \"all\".equals(spanName)) spanName = null;\n\n      if (endTs <= 0) throw new IllegalArgumentException(\"endTs <= 0\");\n      if (limit <= 0) throw new IllegalArgumentException(\"limit <= 0\");\n      if (lookback <= 0) throw new IllegalArgumentException(\"lookback <= 0\");\n      if (minDuration != null) {\n        if (minDuration <= 0) throw new IllegalArgumentException(\"minDuration <= 0\");\n        if (maxDuration != null && maxDuration < minDuration) {\n          throw new IllegalArgumentException(\"maxDuration < minDuration\");\n        }\n      } else if (maxDuration != null) {\n        throw new IllegalArgumentException(\"maxDuration is only valid with minDuration\");\n      }\n\n      return new QueryRequest(\n        serviceName,\n        remoteServiceName,\n        spanName,\n        annotationQuery,\n        minDuration,\n        maxDuration,","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin/src/main/java/zipkin2/storage/QueryRequest.java#L232-L268","documentation":"QueryRequest.Builder.build() validates the assembled query: endTs (epoch millis), limit, and lookback must all be positive, minDuration/maxDuration must be positive microseconds and consistent, else IllegalArgumentException ('endTs <= 0' here). QueryRequest is the value type behind zipkin-server's GET /spans-ish search API, so this fires while constructing a search, not while executing it.","triggerScenarios":"Building a QueryRequest where endTs was never set (primitive long default 0) or was set in seconds, or constructing the builder from HTTP parameters that were blank/non-numeric and coerced to 0.","commonSituations":"Clients omitting endTs expecting 'now'; proxies stripping query parameters; tests building QueryRequest.newBuilder() without endTs; second-vs-millisecond unit mistakes producing 0 after integer division.","solutions":["Always set endTs (and limit, lookback): QueryRequest.newBuilder().endTs(System.currentTimeMillis()).lookback(86400000L).limit(10).serviceName(...).build().","Validate/parse HTTP params at the edge and reject blank values with 400 instead of forwarding 0.","Double-check units: everything is milliseconds except durations, which are microseconds.","Centralize QueryRequest construction in one factory so no call site can forget endTs."],"exampleFix":"// before\nQueryRequest q = QueryRequest.newBuilder().serviceName(\"web\").limit(10).build(); // endTs=0 -> throws\n\n// after\nQueryRequest q = QueryRequest.newBuilder().serviceName(\"web\")\n  .endTs(System.currentTimeMillis())\n  .lookback(86_400_000L)\n  .limit(10)\n  .build();","handlingStrategy":"validation","validationCode":"long now = System.currentTimeMillis();\nQueryRequest q = QueryRequest.newBuilder().serviceName(\"web\").endTs(now).lookback(86_400_000L).limit(10).build();","typeGuard":"boolean canBuildQuery(long endTs, long limit, long lookback) { return endTs > 0 && limit > 0 && lookback > 0; }","tryCatchPattern":null,"preventionTips":["Centralize QueryRequest construction in one factory method that always sets endTs.","Validate HTTP query params at the controller and return 400 for blank/non-numeric values.","Remember units: timestamps/lookback in ms, durations in microseconds."],"tags":["zipkin","query","validation","api"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}