Find owners of deleted filters in Jira cloud
Platform Notice: Cloud Only - This article only applies to Atlassian apps on the cloud platform.
Summary
This article explains how Jira administrators can identify such filters (owned by “Former user”) using the Jira Cloud REST API in case the customer has tons of filters so it is hard to find it by UI.
About filters
In Jira Cloud, some Agile/Kanban boards stop working because the underlying board filter is owned by a deleted user.
When a filter owner is deleted:
Jira changes the display name of filter owner to a “Former user” (localized equivalents may differ).
If a filter owner is deleted and shows as "Former user," the filter and any boards/plans using it will still work—unless the filter is set to private.
The main risk is losing the ability to update permissions or ownership easily.
It's best practice to reassign ownership to an active user to avoid future access or permission issues.
Solution
Finding filter
Create a filter with a specific user.
Delete the specific user(need to wait 14 days due to grace periods)
Try to find the filter from “View all filters”
Also you can find it in System → Shared items → Filters, and the display name of the owner is “Former user”
If you want a systematic resolution you can:
Identify all filters owned by “Former user” using a Python script and the Jira REST API.
For each affected filter, decide how to handle it:
Recreate the filter under an active owner and update any boards to use the new filter, and/or
If the filter is no longer needed, leave it unused or delete it (where possible).
Below is a read-only example script that you can adapt.
The example script provided is intended for demonstration purposes only and is not officially supported by Atlassian. If you choose to use or modify this script, please do so at your own risk, as Atlassian Support can’t assist with troubleshooting, maintenance, or customization of example scripts. For official support, please refer to Atlassian’s supported products and services.
Identify all “Former user” filters via Python (read-only)
This script:
Uses the Jira Cloud REST API
/rest/api/3/filter/search.Lists filters where the owner’s display name is “Former user” (or your localized equivalent).
Writes the results to a CSV for further analysis.
1.1. Prerequisites
Python 3.x installed.
Ability to install Python packages (e.g.,
pip).Jira Cloud:
Site URL (e.g.,
https://your-site.atlassian.net),User email with permission to list filters (site admin recommended),
API token created from https://id.atlassian.com/manage/api-tokens.
Install the requests library (if not already installed):
python3 -m pip install requests
1.2. Python script
Usage (customer-facing): python3 export_former_user_filters.py
This script will:
Print a summary of all filters owned by “Former user” to the console.
Save full details (including JQL) to
jira-filters-former-user.csv.
import base64
import csv
import sys
import requests
# ===== Settings =====
JIRA_BASE_URL = "https://your-site.atlassian.net" # <-- change to your site
EMAIL = "your-email@example.com" # <-- your Atlassian account email
API_TOKEN = "your-api-token" # <-- your API token
OUT_CSV = "./jira-filters-former-user.csv"
# If your Jira is localized and shows a different label than "Former user",
# change this value accordingly (e.g., "元ユーザー" in Japanese).
FORMER_USER_DISPLAY_NAME = "Former user"
# Create Basic auth header
pair = f"{EMAIL}:{API_TOKEN}"
basic = base64.b64encode(pair.encode("utf-8")).decode("utf-8")
headers = {
"Authorization": f"Basic {basic}",
"Accept": "application/json"
}
# Paging settings
max_results = 100
start_at = 0
all_former_user_filters = []
print(f"Searching Jira filters where owner.displayName = '{FORMER_USER_DISPLAY_NAME}'...")
while True:
uri = (
f"{JIRA_BASE_URL}/rest/api/3/filter/search"
f"?expand=owner&maxResults={max_results}&startAt={start_at}"
)
try:
resp = requests.get(uri, headers=headers)
resp.raise_for_status()
except requests.RequestException as e:
print(f"Error during API call: {e}", file=sys.stderr)
break
data = resp.json()
values = data.get("values")
if not values:
break
# Collect filters where the owner is "Former user"
for item in values:
owner = item.get("owner") or {}
if owner.get("displayName") == FORMER_USER_DISPLAY_NAME:
all_former_user_filters.append({
"FilterId": item.get("id"),
"Name": item.get("name"),
"Jql": item.get("jql"),
"OwnerDisplay": owner.get("displayName"),
"OwnerAccountId": owner.get("accountId"),
"SelfUrl": item.get("self"),
"ViewUrl": item.get("viewUrl"),
"SearchUrl": item.get("searchUrl"),
"IsFavourite": item.get("favourite"),
"FavouritedCount": item.get("favouritedCount"),
})
fetched = len(values)
total = data.get("total", start_at + fetched)
start_at += fetched
print(f"Fetched {start_at}/{total} (this page: {fetched})")
if start_at >= total:
break
# Print results & export to CSV
if all_former_user_filters:
print("Matched filters (owned by 'Former user'):")
for f in sorted(all_former_user_filters, key=lambda x: (x["Name"] or "")):
print(
f"FilterId={f['FilterId']}, "
f"Name={f['Name']}, "
f"OwnerDisplay={f['OwnerDisplay']}, "
f"OwnerAccountId={f['OwnerAccountId']}"
)
fieldnames = [
"FilterId",
"Name",
"Jql",
"OwnerDisplay",
"OwnerAccountId",
"SelfUrl",
"ViewUrl",
"SearchUrl",
"IsFavourite",
"FavouritedCount",
]
with open(OUT_CSV, "w", encoding="utf-8", newline="") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(all_former_user_filters)
print(f"Saved CSV → {OUT_CSV}")
else:
print(f"No filters found where owner.displayName = '{FORMER_USER_DISPLAY_NAME}'.")Was this helpful?