diff --git a/modules/markup/markdown/callout/github.go b/modules/markup/markdown/callout/github.go
index 443f6fe2a3..debad42b83 100644
--- a/modules/markup/markdown/callout/github.go
+++ b/modules/markup/markdown/callout/github.go
@@ -36,6 +36,10 @@ func (g *GitHubCalloutTransformer) Transform(node *ast.Document, reader text.Rea
 
 		switch v := n.(type) {
 		case *ast.Blockquote:
+			if v.ChildCount() == 0 {
+				return ast.WalkContinue, nil
+			}
+
 			// We only want attention blockquotes when the AST looks like:
 			// Text: "["
 			// Text: "!TYPE"
diff --git a/modules/markup/markdown/callout/github_legacy.go b/modules/markup/markdown/callout/github_legacy.go
index ce86c10356..eee788e271 100644
--- a/modules/markup/markdown/callout/github_legacy.go
+++ b/modules/markup/markdown/callout/github_legacy.go
@@ -25,6 +25,10 @@ func (g *GitHubLegacyCalloutTransformer) Transform(node *ast.Document, reader te
 
 		switch v := n.(type) {
 		case *ast.Blockquote:
+			if v.ChildCount() == 0 {
+				return ast.WalkContinue, nil
+			}
+
 			// The first paragraph contains the callout type.
 			firstParagraph := v.FirstChild()
 			if firstParagraph.ChildCount() < 1 {
diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go
index 5d33d89748..37d4d9bec4 100644
--- a/modules/markup/markdown/markdown_test.go
+++ b/modules/markup/markdown/markdown_test.go
@@ -1212,3 +1212,17 @@ func TestCustomMarkdownURL(t *testing.T) {
 	test("[test](abp)",
 		`<p><a href="http://localhost:3000/gogits/gogs/src/branch/main/abp" rel="nofollow">test</a></p>`)
 }
+
+func TestCallout(t *testing.T) {
+	setting.AppURL = AppURL
+
+	test := func(input, expected string) {
+		buffer, err := markdown.RenderString(&markup.RenderContext{
+			Ctx: git.DefaultContext,
+		}, input)
+		assert.NoError(t, err)
+		assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
+	}
+
+	test(">\n0", "<blockquote>\n</blockquote>\n<p>0</p>")
+}