diff --git a/forgejo-release.sh b/forgejo-release.sh
index 1474b6a..38aa100 100755
--- a/forgejo-release.sh
+++ b/forgejo-release.sh
@@ -59,7 +59,18 @@ ensure_tag() {
             return 1
         fi
     else
-        api POST repos/$REPO/tags --data-raw '{"tag_name": "'"$TAG"'", "target": "'"$SHA"'"}' >"$TAG_FILE"
+        create_tag
+    fi
+}
+
+create_tag() {
+    api POST repos/$REPO/tags --data-raw '{"tag_name": "'"$TAG"'", "target": "'"$SHA"'"}' >"$TAG_FILE"
+}
+
+delete_tag() {
+    if get_tag; then
+        api DELETE repos/$REPO/tags/$TAG
+        rm -f "$TAG_FILE"
     fi
 }
 
@@ -134,7 +145,7 @@ maybe_override() {
     fi
     api DELETE repos/$REPO/releases/tags/"$TAG" >&/dev/null || true
     if get_tag && ! matched_tag; then
-        api DELETE repos/$REPO/tags/"$TAG"
+        delete_tag
     fi
 }
 
diff --git a/testdata/forgejo-release-test.sh b/testdata/forgejo-release-test.sh
index 97f630c..156fb6b 100755
--- a/testdata/forgejo-release-test.sh
+++ b/testdata/forgejo-release-test.sh
@@ -39,8 +39,18 @@ test_wait_release() {
     ! wait_release
 }
 
+test_create_delete_tag() {
+    delete_tag
+
+    ! get_tag
+    create_tag
+    get_tag
+    delete_tag
+    ! get_tag
+}
+
 test_ensure_tag() {
-    api DELETE repos/$REPO/tags/$TAG || true
+    delete_tag
     #
     # idempotent
     #
@@ -59,7 +69,7 @@ test_ensure_tag() {
         ! matched_tag
         ! ensure_tag
     )
-    api DELETE repos/$REPO/tags/$TAG
+    delete_tag
 }
 
 test_maybe_sign_release_no_gpg() {
@@ -133,6 +143,7 @@ test_run() {
     REPO=$user/$project
     test_setup $project
     test_ensure_tag
+    test_create_delete_tag
     DELAY=0
     test_wait_release_fail
     echo "================================ TEST BEGIN"