{"record":{"id":"c17cc1878bbd0a30","repo":"apache/druid","slug":"lock-datasource-s-task-datasource-s","errorCode":null,"errorMessage":"Lock dataSource[%s] != task dataSource[%s]","messagePattern":"Lock dataSource\\[(.+?)\\] != task dataSource\\[(.+?)\\]","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractFixedIntervalTask.java","lineNumber":111,"sourceCode":"\n  @JsonProperty\n  public Interval getInterval()\n  {\n    return interval;\n  }\n\n  @Override\n  public void stopGracefully(TaskConfig taskConfig)\n  {\n  }\n\n  TaskLock getAndCheckLock(TaskToolbox toolbox) throws IOException\n  {\n    // Confirm we have a lock (will throw if there isn't exactly one element)\n    final TaskLock myLock = Iterables.getOnlyElement(getTaskLocks(toolbox.getTaskActionClient()));\n\n    if (!myLock.getDataSource().equals(getDataSource())) {\n      throw new ISE(\"Lock dataSource[%s] != task dataSource[%s]\", myLock.getDataSource(), getDataSource());\n    }\n\n    if (!myLock.getInterval().equals(getInterval())) {\n      throw new ISE(\"Lock interval[%s] != task interval[%s]\", myLock.getInterval(), getInterval());\n    }\n    return myLock;\n  }\n}\n","sourceCodeStart":93,"sourceCodeEnd":120,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractFixedIntervalTask.java#L93-L120","documentation":"AbstractFixedIntervalTask.getAndCheckLock fetches the single task lock for the task and verifies it matches the task's own datasource (and interval). If the lock's datasource differs from the task's datasource, internal lock/bookkeeping state is inconsistent, so it throws this ISE. It confirms the task only operates under locks that actually belong to it.","triggerScenarios":"getTaskLocks returns a lock whose dataSource differs from the task's datasource — e.g. getTaskLocks overridden/returning foreign locks, lock storage corruption, or a custom task subclass mixing up datasource configuration.","commonSituations":"Custom task subclasses overriding getTaskLocks incorrectly; datasource renamed mid-task; metadata-store/overlord state corruption after failover; copy-pasted task code with mismatched datasource fields.","solutions":["Check the task spec's dataSource matches what the task was actually submitted with; resubmit with a consistent spec.","If a custom subclass overrides getTaskLocks, ensure it filters locks by the task's own ID/datasource.","Inspect task lock records in the metadata store for corruption; clean stale locks and restart the task.","Upgrade Druid if this occurs after an overlord failover with no custom code (known state-consistency bugs)."],"exampleFix":"// before\n@Override\nprotected List<TaskLock> getTaskLocks(TaskActionClient client) {\n  return client.submit(new LockListAction()); // returns locks for ALL tasks\n}\n// after\n@Override\nprotected List<TaskLock> getTaskLocks(TaskActionClient client) {\n  return client.submit(new TaskLocksAcquireAction...) // or filter LockListAction result to this task's id/datasource\n}","handlingStrategy":"validation","validationCode":"List<TaskLock> locks = client.submit(new LockListAction());\nfor (TaskLock lock : locks) {\n  if (!lock.getDataSource().equals(taskDataSource)) {\n    throw new IllegalStateException(\"Lock datasource mismatch: \" + lock.getDataSource());\n  }\n}","typeGuard":"boolean lockBelongsToTask(TaskLock lock, String taskDataSource) {\n  return lock != null && taskDataSource.equals(lock.getDataSource());\n}","tryCatchPattern":"try {\n  TaskLock lock = fixedTask.getAndCheckLock(toolbox);\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"Lock dataSource\")) {\n    // inspect lock storage for corruption/stale locks; restart the task after cleanup\n  } else throw e;\n}","preventionTips":["Filter LockListAction results to locks belonging to this task's ID when overriding getTaskLocks.","Never change a task's datasource between submission and run.","Audit metadata-store lock rows after overlord failovers."],"tags":["indexing-service","locks","datasource"],"backgroundTag":"type-mismatch","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}