vitessio/vitess · error · VitessError
VT03014
VT03014
Error message
VT03014: unknown column '%s' in '%s'
What it means
VT03014 is raised by findDefault in go/vt/vtgate/planbuilder/operators/insert.go:254 when an INSERT references a column that exists in the query's column list but cannot be found in the vschema's authoritative column definitions for the target table. Vitess panics with this error (recovered as a query error) because it needs the column's DEFAULT expression to build the insert plan and cannot proceed without it. It indicates a mismatch between the columns the client is inserting and the columns known to the vschema.
Source
Thrown at go/vt/vtgate/planbuilder/operators/insert.go:254
def = findDefault(vTbl, pCol)
if def == nil {
// If default value is empty, nothing to compare as it will always be false.
return nil, nil
}
}
pIndexes = append(pIndexes, pComp{idx, def, pCol})
pColTuple = append(pColTuple, sqlparser.NewColName(pCol.String()))
}
return
}
func findDefault(vTbl *vindexes.BaseTable, pCol sqlparser.IdentifierCI) sqlparser.Expr {
for _, column := range vTbl.Columns {
if column.Name.Equal(pCol) {
return column.Default
}
}
panic(vterrors.VT03014(pCol.String(), vTbl.Name.String()))
}
type uComp struct {
idx int
def sqlparser.Expr
}
func uniqKeyCompExpressions(vTbl *vindexes.BaseTable, ins *sqlparser.Insert, rows sqlparser.Values) (comps []*sqlparser.ComparisonExpr) {
noOfUniqKeys := len(vTbl.UniqueKeys)
if noOfUniqKeys == 0 {
return nil
}
type uIdx struct {
Indexes [][]uComp
uniqKey []sqlparser.Expr
}
View on GitHub (pinned to 01a25a7d17)
Solutions
- Update the vschema (rebuild the table definition) so it includes the column being inserted
- Check the INSERT column list for typos against SHOW COLUMNS on the underlying table
- Verify ColumnListAuthoritative is only set on tables whose vschema column list truly matches the physical table
Example fix
// before (vschema missing new column)
"t": {"column_vindexes": [...], "columns": [{"name": "id"}, {"name": "name"}]}
// after
"t": {"column_vindexes": [...], "columns": [{"name": "id"}, {"name": "name"}, {"name": "email"}]} Defensive patterns
Strategy: validation
Validate before calling
// Compare INSERT columns against the vschema table definition before executing
const cols = new Set(Object.keys(vschema.tables['t'].columns || {}));
const missing = insertColumns.filter(c => !cols.has(c));
if (missing.length) throw new Error('columns not in vschema: ' + missing.join(',')); Type guard
function isKnownColumn(col, vTbl) {
return vTbl.columns.some(c => c.name.toLowerCase() === col.toLowerCase());
} Try / catch
try {
await vtgate.execute('INSERT INTO t (col) VALUES (?)', [v]);
} catch (e) {
if (String(e).includes('VT03014')) {
await refreshVschema(); // reload table definitions, then retry
}
throw e;
} Prevention
- Regenerate/reload the vschema after every ALTER TABLE
- Keep column lists in the vschema authoritative only when they are complete
- Lint INSERT statements against SHOW COLUMNS output in CI
When it happens
Trigger: Calling findDefault (via findPKIndexes or createUniqueKeyComp during INSERT planning) with a pCol that does not match any column.Name in vTbl.Columns — i.e. the insert column list contains a column absent from the vschema table definition.
Common situations: Vschema is out of date after an ALTER TABLE added a column; a typo in the INSERT column list; inserting into a view or table whose vschema entry omits columns; ColumnListAuthoritative set incorrectly so Vitess trusts an incomplete column list.
Related errors
- VT09004
- value must be either a float64 (interpreted as seconds) or a
- flagutil: NewOptionalFlag requires a non-nil parse function
- flagutil: OptionalFlagValue has no parse function; use a con
- one or two tables must be specified
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/961d962555bc868d.
Report an issue: GitHub.