{"record":{"id":"f5ae32ff694c0c63","repo":"openzipkin/zipkin","slug":"maxduration-minduration","errorCode":null,"errorMessage":"maxDuration < minDuration","messagePattern":"maxDuration < minDuration","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"zipkin/src/main/java/zipkin2/storage/QueryRequest.java","lineNumber":256,"sourceCode":"    }\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,\n        endTs,\n        lookback,\n        limit\n      );\n    }\n","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin/src/main/java/zipkin2/storage/QueryRequest.java#L238-L274","documentation":"Thrown by QueryRequest.Builder.build() when both minDuration and maxDuration are set but maxDuration is smaller than minDuration. The pair defines a duration window in microseconds; an inverted window is logically empty, so Zipkin rejects it eagerly as a caller bug.","triggerScenarios":"Calling .minDuration(50000).maxDuration(10000) on the builder; swapping the two values when wiring UI fields; computing maxDuration from a delta (e.g. minDuration + range) where the delta is negative or the subtraction underflows.","commonSituations":"Two form fields ('min'/'max duration') entered in the wrong order by a user and passed through unvalidated; refactoring that renames variables and accidentally swaps the arguments; off-by-unit bugs that shrink maxDuration below minDuration.","solutions":["Ensure maxDuration >= minDuration, both in microseconds, before calling build()","If the intent is a window, compute max explicitly: maxDuration = minDuration + windowMicros","Add a UI/service-side validation that rejects or swaps inverted min/max pairs before they reach the builder"],"exampleFix":"// before\nbuilder.minDuration(maxDuration).maxDuration(minDuration); // swapped\n\n// after\nbuilder.minDuration(minDuration).maxDuration(maxDuration);","handlingStrategy":"validation","validationCode":"if (minDuration != null && maxDuration != null && maxDuration < minDuration) {\n    throw new IllegalArgumentException(\n        \"maxDuration (\" + maxDuration + \") must be >= minDuration (\" + minDuration + \")\");\n}\nQueryRequest.Builder b = QueryRequest.newBuilder().endTs(endTs).limit(10)\n    .minDuration(minDuration);\nif (maxDuration != null) b.maxDuration(maxDuration);","typeGuard":null,"tryCatchPattern":"try {\n    builder.minDuration(min).maxDuration(max).build();\n} catch (IllegalArgumentException e) {\n    // logical input error: report to user, do not retry\n    throw new BadRequestException(e.getMessage(), e);\n}","preventionTips":["Validate min<=max in UI/service code before the value reaches Zipkin","Derive maxDuration from minDuration plus a positive window instead of independent inputs","Add a unit test covering the inverted-range case"],"tags":["java","zipkin","validation","duration","range"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}