Your migration is done. The champagne has been opened. Then the tickets start rolling in.
"This link in the issue description gives me a 404." "The remote link on PROJ-1234 just shows an endless spinner." "All the @mentions in our old comments point to accounts that don't exist anymore."
I've seen this at nearly every migration project I've consulted on over the past 12 years. The migration itself goes smoothly — Atlassian's tooling handles the heavy lifting. But once users start working in the new environment, the broken links surface everywhere.
It's not just Server-to-Cloud
Most people associate link breakage with DC or Server to Cloud migrations. But I've encountered the exact same problem during Cloud-to-Cloud consolidations — when companies merge and need to bring multiple Atlassian instances together. Same symptoms, same frustration, different context.
The database hack that backfired
At one client, several standalone DC instances were being consolidated into one. The approach seemed pragmatic: run database updates with search-and-replace to swap old URLs for new ones.
The result? Remote Links that had pointed to the real source instance were now showing an endless spinner with "Failed to load." The bulk replacement had rewritten URLs that shouldn't have been touched, and the links were pointing to paths that didn't exist in the target structure.
I started building ScriptRunner endpoints to detect and repair these broken remote links. Custom Groovy code that could parse the link targets, identify which ones were actually broken, and fix them programmatically.
During testing, we discovered it wasn't just remote links. Old URLs were hiding in issue descriptions, comments, custom field values, and environment fields. Every text field that had ever contained a link to the old instance was potentially broken.
What Atlassian's migration doesn't cover
Atlassian's Cloud Migration Assistant handles a lot. But there are well-documented gaps that have been open for years. Environment fields aren't touched. Remote links and web links aren't rewritten. If your project keys changed during migration, issue key references like OLDKEY-123 stay as-is in text fields. User mentions from deactivated accounts remain broken.
These aren't obscure edge cases. There are Atlassian support tickets with dozens of references from affected customers confirming these gaps. For many organizations, this means hundreds or thousands of broken references scattered across their most important issues.
From consulting fix to Marketplace app
The ScriptRunner endpoints I built for that one client kept growing. More pattern types, more field coverage, edge cases I hadn't anticipated. At some point, I realized: this kind of repair work shouldn't require a consultant writing custom scripts every time. The problem is universal enough that a proper tool should exist.
That's how Legacy URL Scanner for Jira was born.
What it covers
The scanner checks descriptions, comments, custom fields, environment fields, and remote links. You configure your old domain mappings — and if you had multiple legacy domains from mergers or rebranding, you can map all of them simultaneously.
For cases where project keys changed during migration, there's an issue key resolver that uses Jira's built-in "key was" history to map old keys to new ones. For broken user mentions, you can import your DC user export and the scanner fuzzy-matches against Cloud accounts.When the User Reference Scanner detects broken mentions, it doesn't just flag them — it prompts you to generate a user export from your migrated DC instance. You get a copy-and-paste ready SQL statement for Postgres, run it against your old database, and upload the resulting CSV directly through your browser. The scanner then fuzzy-matches the DC users against Cloud accounts and lets you fix the references in bulk.
All uploaded user data stays exclusively in your browser's local storage. No legacy user references are permanently stored in the app or in Forge Storage — once you close the session, the data is gone. Your old DC user data never leaves your browser.
Every fix can be previewed before execution. Nothing gets written until you confirm.
Beyond migration: long-term URL governance
One thing I didn't anticipate when building this: it's not just a post-migration tool. Several teams are now using the governance rules — allowlists and blocklists — to continuously monitor their issues for unauthorized or outdated URLs. Scheduled scans catch new legacy links that get copy-pasted from old documentation or emails.
That turned it from a one-time migration cleanup into an ongoing hygiene tool.
Built on Forge — data stays in your instance
Like all my apps, Legacy URL Scanner runs entirely on Atlassian Forge. Three editions, starting with a free tier for scanning and individual fixes.
The reason why there is no "Runs on Atlassian" trust signal.
I deliberately chose not to limit it to the "Runs on Atlassian" trust signal — because scan results need to reach the people who act on them, and those people aren't always in Jira. The migration lead, the project managers waiting for their links to be fixed, the team coordinating the cleanup — they live in Slack or Teams, not in Jira admin pages. That's why there's a built-in notification layer that pushes scan results to Slack, Microsoft Teams, or any custom webhook endpoint.
If you've recently migrated — or are about to — and want to understand the scope of broken links in your instance before users start reporting them, this is what I built it for.
Legacy URL Scanner for Jira on the Atlassian Marketplace
Questions about post-migration link repair or specific migration scenarios? Happy to help in the comments.
PS: For those who prefer DarkMode Theme (just like me) its completely supported :)
C_ Faysal_CFcon_
3 comments