{"record":{"id":"3c1d325c63981d32","repo":"openzipkin/zipkin","slug":"endts-0-3c1d32","errorCode":null,"errorMessage":"endTs <= 0","messagePattern":"endTs <= 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"zipkin-storage/mysql-v1/src/main/java/zipkin2/storage/mysql/v1/MySQLSpanStore.java","lineNumber":106,"sourceCode":"  @Override public Call<List<String>> getServiceNames() {\n    if (!searchEnabled) return Call.emptyList();\n    return getServiceNamesCall.clone();\n  }\n\n  @Override public Call<List<String>> getRemoteServiceNames(String serviceName) {\n    if (serviceName.isEmpty() || !searchEnabled || !schema.hasRemoteServiceName) {\n      return Call.emptyList();\n    }\n    return dataSourceCallFactory.create(new SelectRemoteServiceNames(schema, serviceName));\n  }\n\n  @Override public Call<List<String>> getSpanNames(String serviceName) {\n    if (serviceName.isEmpty() || !searchEnabled) return Call.emptyList();\n    return dataSourceCallFactory.create(new SelectSpanNames(schema, serviceName));\n  }\n\n  @Override public Call<List<DependencyLink>> getDependencies(long endTs, long lookback) {\n    if (endTs <= 0) throw new IllegalArgumentException(\"endTs <= 0\");\n    if (lookback <= 0) throw new IllegalArgumentException(\"lookback <= 0\");\n\n    if (schema.hasPreAggregatedDependencies) {\n      return dataSourceCallFactory.create(new SelectDependencies(schema, epochDays(endTs, lookback)));\n    }\n    return dataSourceCallFactory.create(\n      new AggregateDependencies(schema, endTs * 1000 - lookback * 1000, endTs * 1000));\n  }\n}\n","sourceCodeStart":88,"sourceCodeEnd":116,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin-storage/mysql-v1/src/main/java/zipkin2/storage/mysql/v1/MySQLSpanStore.java#L88-L116","documentation":"Thrown by MySQLSpanStore.getDependencies when the endTs argument is zero or negative. endTs is expected to be an epoch-millisecond timestamp that anchors the dependency-link window. The store validates it up front because the SQL it generates (endTs * 1000 - lookback * 1000) would produce nonsense windows otherwise. A lookback <= 0 is validated the same way on the next line.","triggerScenarios":"Calling MySQLStorage.spanStore().getDependencies(endTs, lookback) with endTs = 0, a negative number, or an uninitialized long. Typically happens when a caller passes seconds instead of millis of passes a default primitive long that was never set.","commonSituations":"Porting code from another storage backend that accepted 0 as 'now', passing System.currentTimeMillis()/1000 (seconds) where millis is expected, or copying the DependencyLink query from a UI that sends endTs as an optional parameter that defaults to 0.","solutions":["Pass endTs as epoch milliseconds, e.g. System.currentTimeMillis(), and a positive lookback in millis.","Validate both arguments at the call site before invoking getDependencies and substitute sane defaults (now, 1 day lookback) when they are unset.","If wrapping the Zipkin query API in a service, reject requests with endTs <= 0 with a 400 response instead of letting the exception escape."],"exampleFix":"// before\nlong endTs = 0; // never set\nCall<List<DependencyLink>> call = storage.spanStore().getDependencies(endTs, lookback);\n\n// after\nlong endTs = System.currentTimeMillis();\nCall<List<DependencyLink>> call = storage.spanStore().getDependencies(endTs, lookback);","handlingStrategy":"validation","validationCode":"long endTs = /* from request */;\nif (endTs <= 0) endTs = System.currentTimeMillis();\nif (lookback <= 0) lookback = 86_400_000L; // 1 day\nCall<List<DependencyLink>> call = storage.spanStore().getDependencies(endTs, lookback);","typeGuard":null,"tryCatchPattern":"try { storage.spanStore().getDependencies(endTs, lookback).execute(); } catch (IllegalArgumentException e) { /* map to 400 Bad Request for the caller */ }","preventionTips":["Treat endTs/lookback as required request parameters and validate them at the API boundary","Remember units: endTs is epoch millis, not seconds"],"tags":["mysql","storage","dependencies","validation","illegal-argument"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}