{"record":{"id":"c26458d9d6ce7068","repo":"thanos-io/thanos","slug":"conflict","errorCode":null,"errorMessage":"conflict","messagePattern":"conflict","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/receive/handler.go","lineNumber":89,"sourceCode":"\t// AllTenantsQueryParam is the query parameter for getting TSDB stats for all tenants.\n\tAllTenantsQueryParam = \"all_tenants\"\n\t// LimitStatsQueryParam is the query parameter for limiting the amount of returned TSDB stats.\n\tLimitStatsQueryParam = \"limit\"\n\t// Labels for metrics.\n\tlabelSuccess = \"success\"\n\tlabelError   = \"error\"\n)\n\ntype ReplicationProtocol string\n\nconst (\n\tProtobufReplication  ReplicationProtocol = \"protobuf\"\n\tCapNProtoReplication ReplicationProtocol = \"capnproto\"\n)\n\nvar (\n\t// errConflict is returned whenever an operation fails due to any conflict-type error.\n\terrConflict = errors.New(\"conflict\")\n\n\terrBadReplica  = errors.New(\"request replica exceeds receiver replication factor\")\n\terrNotReady    = errors.New(\"target not ready\")\n\terrUnavailable = errors.New(\"target not available\")\n\n\terrValidation = errors.New(\"validation error\")\n)\n\ntype WriteableStoreAsyncClient interface {\n\tstorepb.WriteableStoreClient\n\tRemoteWriteAsync(context.Context, *storepb.WriteRequest, endpointReplica, []int, chan writeResponse, func(error))\n\t// TryRemoteWriteAsync submits the request without blocking. Returns false if the peer's\n\t// worker pool is at capacity; the caller should fall back to RemoteWriteAsync.\n\tTryRemoteWriteAsync(context.Context, *storepb.WriteRequest, endpointReplica, []int, chan writeResponse, func(error)) bool\n}\n\n// Options for the web Handler.\ntype Options struct {","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/receive/handler.go#L71-L107","documentation":"errConflict is the sentinel returned by Write and receiveOTLPHTTP whenever a write fails due to a conflict-type error (e.g. the target considers the series/operation conflicting). The HTTP handler maps it to http.StatusConflict (409) and the capnp server maps it to writecapnp.WriteError_alreadyExists. It is matched with errors.Cause, so it must be the root cause of the returned error.","triggerScenarios":"Write or receiveOTLPHTTP returns an error whose root cause is errConflict — a replication target or local store reports a conflicting write that is not a validation, unavailability, or bad-replica error.","commonSituations":"Duplicate/overlapping writes racing on the same series, miswired replication producing out-of-order conflicting state between receiver replicas, clients retrying writes the target already committed.","solutions":["Check which peer returned the conflict and inspect its logs for the underlying store error","Make the write idempotent on the client or deduplicate retries before resending","Verify all receiver replicas share a consistent hashring configuration so conflicting writes don't occur","If you need programmatic handling, compare with errors.Cause(err) == errConflict / errors.Is where wrapping permits"],"exampleFix":"// before\nif err := r.Write(ctx, req); err != nil { return err }\n// after\nif err := r.Write(ctx, req); err != nil {\n    if errors.Is(errors.Cause(err), errConflict) {\n        return status.Error(codes.AlreadyExists, err.Error())\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isConflict(err error) bool {\n    return errors.Is(errors.Cause(err), errConflict)\n}","tryCatchPattern":"err := r.Write(ctx, req)\nif err != nil {\n    switch errors.Cause(err) {\n    case errConflict: http.Error(w, err.Error(), http.StatusConflict)\n    default: http.Error(w, err.Error(), http.StatusInternalServerError)\n    }\n}","preventionTips":["Compare root causes with errors.Cause/errors.Is, since these sentinels are wrapped","Make client writes idempotent to tolerate duplicate delivery","Keep the hashring consistent across all receivers to avoid conflicting writes","Back off retries instead of immediately re-sending conflicting writes"],"tags":["conflict","write","replication"],"backgroundTag":"http-error-response","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}