diff --git a/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionScanRule.java b/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionScanRule.java
index 6cfa31a8e43..c31b86dc50e 100644
--- a/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionScanRule.java
+++ b/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionScanRule.java
@@ -120,7 +120,7 @@ public class SqlInjectionScanRule extends AbstractAppParamPlugin
      * maximise SQL errors Note that we do separate runs for each family of characters, in case one
      * family are filtered out, the others might still get past
      */
-    private static final String[] SQL_CHECK_ERR = {"'", "\"", ";", "'(", ")", "(", "NULL", "'\""};
+    static final String[] SQL_CHECK_ERR = {"'", "\"", ";", "'(", ")", "(", "NULL", "'\""};
 
     /**
      * A collection of RDBMS with its error message fragments and {@code Tech}.
@@ -449,7 +449,7 @@ private static List<String> asList(String... strings) {
      * generic UNION statements. Hoping these will cause a specific error message that we will
      * recognise
      */
-    private static String[] SQL_UNION_APPENDAGES = {
+    static String[] SQL_UNION_APPENDAGES = {
         " UNION ALL select NULL" + SQL_ONE_LINE_COMMENT,
         "' UNION ALL select NULL" + SQL_ONE_LINE_COMMENT,
         "\" UNION ALL select NULL" + SQL_ONE_LINE_COMMENT,
diff --git a/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionScanRuleUnitTest.java b/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionScanRuleUnitTest.java
index bd343731e8a..c31b3b9d07c 100644
--- a/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionScanRuleUnitTest.java
+++ b/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionScanRuleUnitTest.java
@@ -31,8 +31,10 @@
 import fi.iki.elonen.NanoHTTPD.IHTTPSession;
 import fi.iki.elonen.NanoHTTPD.Response;
 import java.util.Map;
+import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.parosproxy.paros.core.scanner.Alert;
+import org.parosproxy.paros.core.scanner.Plugin.AlertThreshold;
 import org.parosproxy.paros.core.scanner.Plugin.AttackStrength;
 import org.zaproxy.addon.commonlib.CommonAlertTag;
 import org.zaproxy.zap.model.Tech;
@@ -376,6 +378,196 @@ void shouldAlertByBodyComparisonIgnoringXmlEscapedPayload() throws Exception {
         assertThat(actual.getAttack(), is(equalTo(attackPayload)));
     }
 
+    @Nested
+    class ErrorBasedSqlInjection {
+        @Test
+        void shouldAlert_emptyPrefix() throws Exception {
+            // Given
+            final String param = "param";
+            final String normalValue = "test";
+            final String emptyPrefixErrorValue = "" + SqlInjectionScanRule.SQL_CHECK_ERR[0];
+
+            final UrlParamValueHandler handler =
+                    UrlParamValueHandler.builder()
+                            .targetParam(param)
+                            .whenParamValueIs(param)
+                            .thenReturnHtml(normalValue)
+                            .whenParamValueIs(emptyPrefixErrorValue)
+                            .thenReturnHtml("You have an error in your SQL syntax")
+                            .build();
+            nano.addHandler(handler);
+            rule.init(getHttpMessage("/?param=" + normalValue), parent);
+
+            // When
+            rule.scan();
+
+            // Then
+            assertThat(alertsRaised, hasSize(1));
+        }
+
+        @Test
+        void shouldAlert_originalParamPrefix() throws Exception {
+            // Given
+            final String param = "param";
+            final String normalValue = "test";
+            final String originalParamErrorValue =
+                    normalValue + SqlInjectionScanRule.SQL_CHECK_ERR[0];
+
+            final UrlParamValueHandler handler =
+                    UrlParamValueHandler.builder()
+                            .targetParam(param)
+                            .whenParamValueIs(param)
+                            .thenReturnHtml(normalValue)
+                            .whenParamValueIs(originalParamErrorValue)
+                            .thenReturnHtml("You have an error in your SQL syntax")
+                            .build();
+            nano.addHandler(handler);
+            rule.init(getHttpMessage("/?param=" + normalValue), parent);
+
+            // When
+            rule.scan();
+
+            // Then
+            assertThat(alertsRaised, hasSize(1));
+        }
+
+        @Test
+        void shouldNotAlert_nonSqlMessage() throws Exception {
+            // Given
+            final String param = "param";
+            final String normalValue = "test";
+            final String originalParamErrorValue =
+                    normalValue + SqlInjectionScanRule.SQL_CHECK_ERR[0];
+
+            final UrlParamValueHandler handler =
+                    UrlParamValueHandler.builder()
+                            .targetParam(param)
+                            .whenParamValueIs(param)
+                            .thenReturnHtml(normalValue)
+                            .whenParamValueIs(originalParamErrorValue)
+                            .thenReturnHtml("Not a SQL error message")
+                            .build();
+            nano.addHandler(handler);
+            rule.init(getHttpMessage("/?param=" + normalValue), parent);
+
+            // When
+            rule.scan();
+
+            // Then
+            assertThat(alertsRaised, hasSize(0));
+        }
+
+        @Test
+        void shouldAlert_genericRDBMSError() throws Exception {
+            // Given
+            rule.setAlertThreshold(
+                    AlertThreshold.LOW); // Generic are currently only checked at the low threshold
+            final String param = "param";
+            final String normalValue = "test";
+            final String originalParamErrorValue =
+                    normalValue + SqlInjectionScanRule.SQL_CHECK_ERR[0];
+
+            final UrlParamValueHandler handler =
+                    UrlParamValueHandler.builder()
+                            .targetParam(param)
+                            .whenParamValueIs(param)
+                            .thenReturnHtml(normalValue)
+                            .whenParamValueIs(originalParamErrorValue)
+                            .thenReturnHtml("java.sql.SQLException")
+                            .build();
+            nano.addHandler(handler);
+            rule.init(getHttpMessage("/?param=" + normalValue), parent);
+
+            // When
+            rule.scan();
+
+            // Then
+            assertThat(alertsRaised, hasSize(1));
+        }
+    }
+
+    @Nested
+    class UnionBasedSqlInjection {
+        @Test
+        void shouldAlert_RDBMSErrorMessage() throws Exception {
+            // Given
+            final String param = "param";
+            final String normalValue = "test";
+            final String unionValueString =
+                    normalValue + SqlInjectionScanRule.SQL_UNION_APPENDAGES[0];
+
+            final UrlParamValueHandler handler =
+                    UrlParamValueHandler.builder()
+                            .targetParam(param)
+                            .whenParamValueIs(param)
+                            .thenReturnHtml(normalValue)
+                            .whenParamValueIs(unionValueString)
+                            .thenReturnHtml("You have an error in your SQL syntax")
+                            .build();
+            nano.addHandler(handler);
+            rule.init(getHttpMessage("/?param=" + normalValue), parent);
+
+            // When
+            rule.scan();
+
+            // Then
+            assertThat(alertsRaised, hasSize(1));
+        }
+
+        @Test
+        void shouldNotAlert_nonErrorMessageResponse() throws Exception {
+            // Given
+            final String param = "param";
+            final String normalValue = "test";
+            final String unionValueString =
+                    normalValue + SqlInjectionScanRule.SQL_UNION_APPENDAGES[0];
+
+            final UrlParamValueHandler handler =
+                    UrlParamValueHandler.builder()
+                            .targetParam(param)
+                            .whenParamValueIs(param)
+                            .thenReturnHtml(normalValue)
+                            .whenParamValueIs(unionValueString)
+                            .thenReturnHtml("This is not a sql error message")
+                            .build();
+            nano.addHandler(handler);
+            rule.init(getHttpMessage("/?param=" + normalValue), parent);
+
+            // When
+            rule.scan();
+
+            // Then
+            assertThat(alertsRaised, hasSize(0));
+        }
+
+        @Test
+        void shouldNotRun_strengthLOW() throws Exception {
+            // Given
+            rule.setAttackStrength(AttackStrength.LOW);
+            final String param = "param";
+            final String normalValue = "test";
+            final String unionValueString =
+                    normalValue + SqlInjectionScanRule.SQL_UNION_APPENDAGES[0];
+
+            final UrlParamValueHandler handler =
+                    UrlParamValueHandler.builder()
+                            .targetParam(param)
+                            .whenParamValueIs(param)
+                            .thenReturnHtml(normalValue)
+                            .whenParamValueIs(unionValueString)
+                            .thenReturnHtml("You have an error in your SQL syntax")
+                            .build();
+            nano.addHandler(handler);
+            rule.init(getHttpMessage("/?param=" + normalValue), parent);
+
+            // When
+            rule.scan();
+
+            // Then
+            assertThat(alertsRaised, hasSize(0));
+        }
+    }
+
     private static class ExpressionBasedHandler extends NanoServerHandler {
 
         public enum Expression {