alibaba/nacos · error · SQLException
Unsupported SQL: %s. Nacos only support DML and some DDL SQL
Error message
Unsupported SQL: %s. Nacos only support DML and some DDL SQL.
What it means
Thrown by SqlTypeLimiter.throwException (private) as a SQLException when an SQL statement's first token is not an allowed DML verb (INSERT/UPDATE/DELETE/SELECT) nor an allowed DDL verb (CREATE/ALTER), or when CREATE/ALTER is followed by a second token not in {SCHEMA, TABLE, INDEX}. The limiter guards embedded Derby SQL execution and is enabled by default (nacos.persistence.sql.derby.limit.enabled=true).
Source
Thrown at persistence/src/main/java/com/alibaba/nacos/persistence/repository/embedded/sql/limiter/SqlTypeLimiter.java:133
}
if (!allowedDdlSqls.contains(firstToken)) {
throwException(trimmedSql);
}
checkSqlForSecondToken(firstTokenIndex, trimmedSql);
}
@Override
public void doLimit(List<String> sql) throws SQLException {
if (null == sql || !enabledLimit) {
return;
}
for (String each : sql) {
doLimit(each);
}
}
private void throwException(String sql) throws SQLException {
throw new SQLException(
String.format("Unsupported SQL: %s. Nacos only support DML and some DDL SQL.", sql));
}
private void checkSqlForSecondToken(int firstTokenIndex, String trimmedSql)
throws SQLException {
int secondTokenIndex = trimmedSql.indexOf(" ", firstTokenIndex + 1);
if (-1 == secondTokenIndex) {
secondTokenIndex = trimmedSql.length();
}
String secondToken =
trimmedSql.substring(firstTokenIndex + 1, secondTokenIndex).toUpperCase();
if (!allowedDdlScopes.contains(secondToken)) {
throwException(trimmedSql);
}
}
}
View on GitHub (pinned to 9b989acdf1)
Solutions
- Restrict SQL to INSERT/UPDATE/DELETE/SELECT, or CREATE SCHEMA/TABLE/INDEX, or ALTER TABLE.
- If you legitimately need a disallowed statement, re-evaluate: the limiter is a safety control for embedded Derby, not a toggle for arbitrary DDL.
- To disable the limiter for a controlled maintenance operation set nacos.persistence.sql.derby.limit.enabled=false (do this only in a trusted, isolated maintenance window).
Example fix
// before: DROP is not allowed by the limiter
doLimit("DROP TABLE config_info");
// after: use the supported DDL scope, or disable limiter for trusted maintenance
// only if strictly necessary
// System.setProperty("nacos.persistence.sql.derby.limit.enabled", "false"); Defensive patterns
Strategy: validation
Validate before calling
private static final Set<String> OK_VERBS = Set.of(
"INSERT","UPDATE","DELETE","SELECT","CREATE","ALTER");
private static final Set<String> OK_DDL_SCOPE = Set.of("SCHEMA","TABLE","INDEX");
static boolean isAllowedByLimiter(String sql) {
String t = sql.trim().toUpperCase();
String first = t.contains(" ") ? t.substring(0, t.indexOf(' ')) : t;
if (!OK_VERBS.contains(first)) return false;
if (Set.of("CREATE","ALTER").contains(first)) {
int s = t.indexOf(' '), e = t.indexOf(' ', s + 1);
String second = t.substring(s + 1, e < 0 ? t.length() : e);
return OK_DDL_SCOPE.contains(second);
}
return true;
} Type guard
static boolean isAllowedByLimiter(String sql) { /* see validationCode */ return false; } Try / catch
try {
databaseOperate.update(sqlCtx);
} catch (SQLException e) {
if (e.getMessage().startsWith("Unsupported SQL:")) {
// rejected by SqlTypeLimiter; do not retry with the same SQL
throw new IllegalStateException("blocked SQL", e);
}
throw e;
} Prevention
- Only issue INSERT/UPDATE/DELETE/SELECT or CREATE SCHEMA/TABLE/INDEX or ALTER TABLE to embedded Derby.
- Do not send DROP/TRUNCATE/GRANT/DCL through the embedded store.
- Keep nacos.persistence.sql.derby.limit.enabled=true in production.
When it happens
Trigger: Executing SQL against the embedded Derby store whose leading verb is disallowed (e.g. DROP, TRUNCATE, GRANT), or a CREATE/ALTER whose target is not SCHEMA/TABLE/INDEX (e.g. CREATE VIEW). Reached via ModifyRequest/SelectRequest SQL passed to databaseOperate.
Common situations: Custom plugins or maintenance code issuing raw SQL to the embedded store; migrations that use DROP or DCL; trying to run a CREATE PROCEDURE or CREATE VIEW which the limiter rejects.
Related errors
- pageNo and pageSize must be greater than zero
- SERVER_ERROR
- SERVER_ERROR
- PARAMETER_VALIDATE_ERROR
- Path traversal detected: {path}
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/7d966ee9cb0f56e4.
Report an issue: GitHub.