provectus/kafka-ui · error · ValidationException

Invalid syntax:

Error message

Invalid syntax: 

What it means

KsqlGrammar configures an ANTLR lexer/parser with a BaseErrorListener that converts any ANTLR syntaxError callback into a ValidationException('Invalid syntax: <msg>'). It fires during tokenization/parsing of a ksql statement that does not conform to the ksql grammar.

Solutions

  1. Fix the ksql statement syntax reported by the ANTLR message appended after 'Invalid syntax: '
  2. Test the query in ksqlDB CLI to confirm valid ksql syntax
  3. Check for unsupported statements/keywords in the grammar used by kafka-ui
  4. Verify quoting of identifiers and string literals

Example fix

// before
KsqlGrammar.parseStatements("SELCT * FROM orders;")
// after
KsqlGrammar.parseStatements("SELECT * FROM orders;");
Defensive patterns

Strategy: try-catch

Validate before calling

// Basic sanity before sending ksql
String q = query.trim().toUpperCase();
if (!(q.startsWith("SELECT") || q.startsWith("CREATE") || q.startsWith("INSERT") || q.startsWith("SHOW") || q.startsWith("DESCRIBE") || q.startsWith("DROP") || q.startsWith("PRINT") || q.startsWith("TERMINATE") || q.startsWith("EXPLAIN") || q.startsWith("LIST"))) {
  throw new IllegalArgumentException("Not a ksql statement");
}
if (!query.trim().endsWith(";")) throw new IllegalArgumentException("ksql statements must end with ';'");

Try / catch

try {
  Flux<KsqlResponseTable> tables = ksqlService.execute(commandId);
} catch (ValidationException e) {
  if (e.getMessage().startsWith("Invalid syntax:")) {
    log.error("ksql syntax error: {}", e.getMessage().substring("Invalid syntax:".length()));
  } else { throw e; }
}

Prevention

When it happens

Trigger: Submitting a ksql query via KsqlServiceV2/parseStatements whose text violates the grammar — typos in keywords, missing semicolons, unsupported statements, malformed identifiers.

Common situations: Queries written for a different ksqlDB version with syntax kafka-ui's bundled grammar doesn't accept; plain SQL (not ksql) pasted in; unbalanced quotes/parentheses; copy-paste artifacts.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08). Data as JSON: /api/errors/8fba8525c6bde36a. Report an issue: GitHub.

Appendix: source

Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ksql/KsqlGrammar.java:54

    }
    return Optional.of(new KsqlStatements(parsed.singleStatement()));
  }

  static boolean isSelect(KsqlGrammarParser.SingleStatementContext statement) {
    return statement.statement() instanceof ksql.KsqlGrammarParser.QueryStatementContext;
  }

  private static ksql.KsqlGrammarParser.StatementsContext parseStatements(final String sql) {
    var lexer = new KsqlGrammarLexer(CaseInsensitiveStream.from(CharStreams.fromString(sql)));
    var tokenStream = new CommonTokenStream(lexer);
    var grammarParser = new ksql.KsqlGrammarParser(tokenStream);

    lexer.addErrorListener(new BaseErrorListener() {
      @Override
      public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol,
                              int line, int charPositionInLine,
                              String msg, RecognitionException e) {
        throw new ValidationException("Invalid syntax: " + msg);
      }
    });
    grammarParser.getInterpreter().setPredictionMode(PredictionMode.LL);
    try {
      return grammarParser.statements();
    } catch (Exception e) {
      throw new ValidationException("Error parsing ksql query: " + e.getMessage());
    }
  }

  // impl copied from https://github.com/confluentinc/ksql/blob/master/ksqldb-parser/src/main/java/io/confluent/ksql/parser/CaseInsensitiveStream.java
  @RequiredArgsConstructor
  private static class CaseInsensitiveStream implements CharStream {
    @Delegate
    final CharStream stream;

    public static CaseInsensitiveStream from(CharStream stream) {
      // we only need to override LA method

View on GitHub (pinned to 83b5a60cc0)