diff --git a/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap b/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap
index 9d40fd5b7d4d7d1423331901205b4ec1640dad44..500591aef747539252de31b01c35b0951d7a386e 100644
--- a/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap
+++ b/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap
@@ -456,6 +456,21 @@ Array [
 ]
 `;
 
+exports[`platform/gitea/gitea-helper getIssue should call /api/v1/repos/[repo]/issues/[issue] endpoint 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "gitea.renovatebot.com",
+      "user-agent": "https://github.com/renovatebot/renovate",
+    },
+    "method": "GET",
+    "url": "https://gitea.renovatebot.com/api/v1/repos/some/repo/issues/7",
+  },
+]
+`;
+
 exports[`platform/gitea/gitea-helper getOrgLabels should call /api/v1/orgs/[org]/labels endpoint 1`] = `
 Array [
   Object {
diff --git a/lib/platform/gitea/gitea-helper.spec.ts b/lib/platform/gitea/gitea-helper.spec.ts
index 225dcc3e5518ab33b140e672431c029af163faab..4095b539dc8004931ecf8018008351ce0ca66195 100644
--- a/lib/platform/gitea/gitea-helper.spec.ts
+++ b/lib/platform/gitea/gitea-helper.spec.ts
@@ -508,6 +508,19 @@ describe(getName(), () => {
     });
   });
 
+  describe('getIssue', () => {
+    it('should call /api/v1/repos/[repo]/issues/[issue] endpoint', async () => {
+      httpMock
+        .scope(baseUrl)
+        .get(`/repos/${mockRepo.full_name}/issues/${mockIssue.number}`)
+        .reply(200, mockIssue);
+
+      const res = await ght.getIssue(mockRepo.full_name, mockIssue.number);
+      expect(res).toEqual(mockIssue);
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+  });
+
   describe('getRepoLabels', () => {
     it('should call /api/v1/repos/[repo]/labels endpoint', async () => {
       httpMock
diff --git a/lib/platform/gitea/gitea-helper.ts b/lib/platform/gitea/gitea-helper.ts
index f0c9a0b36c12833d378a3cee3b23c6d544a39ed8..88e2bec406546311add2b229f6c36a3e2cbd9215 100644
--- a/lib/platform/gitea/gitea-helper.ts
+++ b/lib/platform/gitea/gitea-helper.ts
@@ -400,6 +400,16 @@ export async function searchIssues(
   return res.body;
 }
 
+export async function getIssue(
+  repoPath: string,
+  idx: number,
+  options?: GiteaHttpOptions
+): Promise<Issue> {
+  const url = `repos/${repoPath}/issues/${idx}`;
+  const res = await giteaHttp.getJson<Issue>(url, options);
+  return res.body;
+}
+
 export async function getRepoLabels(
   repoPath: string,
   options?: GiteaHttpOptions
diff --git a/lib/platform/gitea/index.spec.ts b/lib/platform/gitea/index.spec.ts
index 8d42f712ec1ba855aca4d0466934a43329f44150..d5ab8c01d8dcd1ca2cfb1af2ffe2a00650250f6f 100644
--- a/lib/platform/gitea/index.spec.ts
+++ b/lib/platform/gitea/index.spec.ts
@@ -905,10 +905,24 @@ describe(getName(), () => {
     });
   });
 
+  describe('getIssue', () => {
+    it('should return the issue', async () => {
+      const mockIssue = mockIssues.find((i) => i.number === 1);
+      helper.getIssue.mockResolvedValueOnce(mockIssue);
+      await initFakeRepo();
+
+      expect(await gitea.getIssue(mockIssue.number)).toHaveProperty(
+        'number',
+        mockIssue.number
+      );
+    });
+  });
+
   describe('findIssue', () => {
     it('should return existing open issue', async () => {
       const mockIssue = mockIssues.find((i) => i.title === 'open-issue');
       helper.searchIssues.mockResolvedValueOnce(mockIssues);
+      helper.getIssue.mockResolvedValueOnce(mockIssue);
       await initFakeRepo();
 
       expect(await gitea.findIssue(mockIssue.title)).toHaveProperty(
diff --git a/lib/platform/gitea/index.ts b/lib/platform/gitea/index.ts
index a09a65b261d490e3893a0b40377afefc3534d27e..0458ff5758f7fe17a94c68a52e0eca3b2ddac9ee 100644
--- a/lib/platform/gitea/index.ts
+++ b/lib/platform/gitea/index.ts
@@ -587,16 +587,34 @@ const platform: Platform = {
     return config.issueList;
   },
 
+  async getIssue(number: number, useCache = true): Promise<Issue> {
+    try {
+      const body = (
+        await helper.getIssue(config.repository, number, {
+          useCache,
+        })
+      ).body;
+      return {
+        number,
+        body,
+      };
+    } catch (err) /* istanbul ignore next */ {
+      logger.debug({ err, number }, 'Error getting issue');
+      return null;
+    }
+  },
+
   async findIssue(title: string): Promise<Issue> {
     const issueList = await platform.getIssueList();
     const issue = issueList.find(
       (i) => i.state === 'open' && i.title === title
     );
 
-    if (issue) {
-      logger.debug(`Found Issue #${issue.number}`);
+    if (!issue) {
+      return null;
     }
-    return issue ?? null;
+    logger.debug(`Found Issue #${issue.number}`);
+    return platform.getIssue(issue.number);
   },
 
   async ensureIssue({
@@ -836,6 +854,7 @@ export const {
   getBranchPr,
   getBranchStatus,
   getBranchStatusCheck,
+  getIssue,
   getRawFile,
   getJsonFile,
   getIssueList,
diff --git a/lib/platform/github/index.ts b/lib/platform/github/index.ts
index ec07b151259977e53d55c5ae29137c8874586279..0363732eee9cc61fa7bc41f1e98b7c45bfbad532 100644
--- a/lib/platform/github/index.ts
+++ b/lib/platform/github/index.ts
@@ -1105,6 +1105,27 @@ export async function getIssueList(): Promise<Issue[]> {
   return config.issueList;
 }
 
+export async function getIssue(
+  number: number,
+  useCache = true
+): Promise<Issue | null> {
+  try {
+    const issueBody = (
+      await githubApi.getJson<{ body: string }>(
+        `repos/${config.parentRepo || config.repository}/issues/${number}`,
+        { useCache }
+      )
+    ).body.body;
+    return {
+      number,
+      body: issueBody,
+    };
+  } catch (err) /* istanbul ignore next */ {
+    logger.debug({ err, number }, 'Error getting issue');
+    return null;
+  }
+}
+
 export async function findIssue(title: string): Promise<Issue | null> {
   logger.debug(`findIssue(${title})`);
   const [issue] = (await getIssueList()).filter(
@@ -1114,15 +1135,7 @@ export async function findIssue(title: string): Promise<Issue | null> {
     return null;
   }
   logger.debug(`Found issue ${issue.number}`);
-  const issueBody = (
-    await githubApi.getJson<{ body: string }>(
-      `repos/${config.parentRepo || config.repository}/issues/${issue.number}`
-    )
-  ).body.body;
-  return {
-    number: issue.number,
-    body: issueBody,
-  };
+  return getIssue(issue.number);
 }
 
 async function closeIssue(issueNumber: number): Promise<void> {
diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts
index 748b072c16b8701daa7c2f95f133e4758010bf55..da190b10893409da0906d8ade34020f8422e1d60 100755
--- a/lib/platform/gitlab/index.ts
+++ b/lib/platform/gitlab/index.ts
@@ -753,23 +753,36 @@ export async function getIssueList(): Promise<GitlabIssue[]> {
   return config.issueList;
 }
 
-export async function findIssue(title: string): Promise<Issue | null> {
-  logger.debug(`findIssue(${title})`);
+export async function getIssue(
+  number: number,
+  useCache = true
+): Promise<Issue | null> {
   try {
-    const issueList = await getIssueList();
-    const issue = issueList.find((i) => i.title === title);
-    if (!issue) {
-      return null;
-    }
     const issueBody = (
       await gitlabApi.getJson<{ description: string }>(
-        `projects/${config.repository}/issues/${issue.iid}`
+        `projects/${config.repository}/issues/${number}`,
+        { useCache }
       )
     ).body.description;
     return {
-      number: issue.iid,
+      number,
       body: issueBody,
     };
+  } catch (err) /* istanbul ignore next */ {
+    logger.debug({ err, number }, 'Error getting issue');
+    return null;
+  }
+}
+
+export async function findIssue(title: string): Promise<Issue | null> {
+  logger.debug(`findIssue(${title})`);
+  try {
+    const issueList = await getIssueList();
+    const issue = issueList.find((i) => i.title === title);
+    if (!issue) {
+      return null;
+    }
+    return getIssue(issue.iid);
   } catch (err) /* istanbul ignore next */ {
     logger.warn('Error finding issue');
     return null;
diff --git a/lib/platform/types.ts b/lib/platform/types.ts
index 240425ace74b9ff8481cd59c05d28ea23e6642e2..dc73dda2298009adc455b927d33f4f2fee128cc8 100644
--- a/lib/platform/types.ts
+++ b/lib/platform/types.ts
@@ -139,6 +139,7 @@ export type EnsureIssueResult = 'updated' | 'created';
 export interface Platform {
   findIssue(title: string): Promise<Issue | null>;
   getIssueList(): Promise<Issue[]>;
+  getIssue?(number: number, useCache?: boolean): Promise<Issue>;
   getVulnerabilityAlerts(): Promise<VulnerabilityAlert[]>;
   getRawFile(fileName: string, repo?: string): Promise<string | null>;
   getJsonFile(fileName: string, repo?: string): Promise<any | null>;