{"record":{"id":"100c9129e4810f59","repo":"temporalio/temporal","slug":"cannot-set-current-time-for-current-cluster","errorCode":null,"errorMessage":"Cannot set current time for current cluster","messagePattern":"Cannot set current time for current cluster","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"service/history/shard/context_impl.go","lineNumber":1456,"sourceCode":"\t\treturn time.Time{}, false\n\t}\n\t// An unset visibility time would date the age from the epoch.\n\tif oldest := resp.Tasks[0].GetVisibilityTime(); !oldest.IsZero() {\n\t\treturn oldest, true\n\t}\n\treturn time.Time{}, false\n}\n\nfunc (s *ContextImpl) SetCurrentTime(cluster string, currentTime time.Time) {\n\ts.wLock()\n\tdefer s.wUnlock()\n\tif cluster != s.GetClusterMetadata().GetCurrentClusterName() {\n\t\tprevTime := s.getOrUpdateRemoteClusterInfoLocked(cluster).CurrentTime\n\t\tif prevTime.Before(currentTime) {\n\t\t\ts.getOrUpdateRemoteClusterInfoLocked(cluster).CurrentTime = currentTime\n\t\t}\n\t} else {\n\t\tpanic(\"Cannot set current time for current cluster\")\n\t}\n}\n\nfunc (s *ContextImpl) GetCurrentTime(cluster string) time.Time {\n\tif cluster != s.GetClusterMetadata().GetCurrentClusterName() {\n\t\ts.wLock()\n\t\tdefer s.wUnlock()\n\t\treturn s.getOrUpdateRemoteClusterInfoLocked(cluster).CurrentTime\n\t}\n\treturn s.timeSource.Now().UTC()\n}\n\nfunc (s *ContextImpl) getLastUpdatedTime() time.Time {\n\ts.rLock()\n\tdefer s.rUnlock()\n\treturn s.lastUpdated\n}\n","sourceCodeStart":1438,"sourceCodeEnd":1474,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/history/shard/context_impl.go#L1438-L1474","documentation":"This panic is fired by the history shard context's SetCurrentTime when a caller attempts to update the clock for the cluster that this shard is currently serving. The current cluster's time is owned by the shard's internal timeSource and must never be overwritten by replication, so any attempt to do so is treated as a programming-invariant violation. SetCurrentTime is only valid for remote clusters whose clock is tracked from incoming replication tasks.","triggerScenarios":"Calling ContextImpl.SetCurrentTime(cluster, t) where cluster equals ClusterMetadata.GetCurrentClusterName(); i.e. a replication-history-task processor passes its own cluster name instead of a remote cluster name (typically a misconfigured replication queue or a cluster name sourced from the wrong metadata field).","commonSituations":"Multi-cluster (cross-DC) replication setups where the current cluster name is misconfigured (e.g. 'historyCfg.CurrentClusterName' in config differs between frontend/history services), or custom code that replays tasks locally without filtering out tasks originating from the local cluster.","solutions":["Check the caller of SetCurrentTime and skip the call when the task's cluster name equals the current cluster name (compare against GetClusterMetadata().GetCurrentClusterName()).","Verify the 'current cluster name' setting in the history service config matches across all services in the ring (frontend, history, worker).","If consuming replication tasks, ensure tasks for the local cluster are dropped or handled locally, never routed into the remote-clock update path.","Upgrade/align all nodes to the same cluster-name configuration; a split-brain where one node thinks it is cluster A and another cluster B causes this panic."],"exampleFix":"// before\ns.shardContext.SetCurrentTime(clusterName, task.GetVisibilityTime())\n\n// after\nif clusterName != s.clusterMetadata.GetCurrentClusterName() {\n    s.shardContext.SetCurrentTime(clusterName, task.GetVisibilityTime())\n}","handlingStrategy":"validation","validationCode":"if clusterName == clusterMetadata.GetCurrentClusterName() {\n    return // skip SetCurrentTime for the local cluster\n}\nshardContext.SetCurrentTime(clusterName, t)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always compare the task's cluster name against GetCurrentClusterName() before setting remote clocks","Keep the current-cluster-name config identical across all services and nodes","Filter out locally-originated tasks in replication processing loops","Cover multi-cluster clock updates with integration tests per cluster role"],"tags":["history-service","replication","multi-cluster","panic"],"backgroundTag":"cluster-name-misconfiguration","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}