vitessio/vitess · error
empty create table statement for %v
Error message
empty create table statement for %v
What it means
normalizedSchema executes `SHOW CREATE TABLE db.table` and expects at least one row containing the CREATE statement. Zero rows means MySQL gave no table definition, so normalization fails with this error.
Source
Thrown at go/vt/mysqlctl/schema.go:255
if !tableSchemaOnly {
fields, columns, err = mysqld.GetColumns(ctx, dbName, tableName)
if err != nil {
return nil, nil, "", err
}
}
return fields, columns, schema, nil
}
// normalizedSchema returns a table schema with database names replaced, and auto_increment annotations removed.
func (mysqld *Mysqld) normalizedSchema(ctx context.Context, dbName, tableName, tableType string) (string, error) {
backtickDBName := sqlescape.EscapeID(dbName)
qr, fetchErr := mysqld.FetchSuperQuery(ctx, fmt.Sprintf("SHOW CREATE TABLE %s.%s", backtickDBName, sqlescape.EscapeID(tableName)))
if fetchErr != nil {
return "", vterrors.Wrapf(fetchErr, "in Mysqld.normalizedSchema()")
}
if len(qr.Rows) == 0 {
return "", fmt.Errorf("empty create table statement for %v", tableName)
}
// Normalize & remove auto_increment because it changes on every insert
// FIXME(alainjobart) find a way to share this with
// vt/tabletserver/table_info.go:162
norm := qr.Rows[0][1].ToString()
norm = autoIncr.ReplaceAllLiteralString(norm, "")
if tableType == tmutils.TableView {
// Views will have the dbname in there, replace it
// with {{.DatabaseName}}
norm = strings.ReplaceAll(norm, backtickDBName, "{{.DatabaseName}}")
}
return norm, nil
}
// ResolveTables returns a list of actual tables+views matching a list
// of regexpsView on GitHub (pinned to 01a25a7d17)
Solutions
- Confirm the table exists: run `SHOW CREATE TABLE db.table` manually
- Refresh the table list before export (re-run GetSchema after DDL completes)
- Check for concurrent schema migrations and retry after they finish
- If the table legitimately cannot be shown (permissions), grant SELECT/SHOW privileges to the vt user
Example fix
// before: iterating a stale table list containing dropped_table // after: re-list tables first // SHOW TABLES FROM db; then normalizedSchema for existing tables only
Defensive patterns
Strategy: validation
Validate before calling
qr, err := mysqld.FetchSuperQuery(ctx, "SHOW TABLES FROM "+sqlescape.EscapeID(dbName))
if err == nil {
existing := map[string]bool{}
for _, r := range qr.Rows { existing[r[0].ToString()] = true }
if !existing[tableName] {
return fmt.Errorf("table %s.%s does not exist", dbName, tableName)
}
} Try / catch
norm, err := mysqld.NormalizedSchema(ctx, dbName, tableName)
if err != nil && strings.Contains(err.Error(), "empty create table statement") {
log.Warn("table missing during schema export; refreshing table list")
return refreshAndRetry(dbName)
} Prevention
- Refresh table lists immediately before schema export
- Block DDL migrations during schema export windows
- Grant SHOW/SELECT privileges to the vt MySQL user
When it happens
Trigger: Calling collectSchema/GetSchema for a table that returns no rows from SHOW CREATE TABLE — typically the table was dropped concurrently, doesn't exist, or the server responds unusually.
Common situations: Schema drift between topodata and MySQL (table dropped while exporting); querying views/materialized structures unsupported by the flavor; stale table lists captured before a DROP.
Related errors
- empty create database statement for %v
- no port variable in mysql
- no read_only variable in mysql
- could not parse server version from: %s
- timed out after %v waiting for the dba user to have the requ
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/866ea0fc202979f2.
Report an issue: GitHub.