jaegertracing/jaeger · error

unknown column for position: %q

Error message

unknown column for position: %q

What it means

KeyValue.MarshalUDT implements gocql's UDTMarshaller; Cassandra sends the UDT field names for the tag UDT and each must match a known column (tag_key, tag_type, value_string, value_bool, value_int64, value_double, value_binary). Any other name means the Cassandra-side UDT schema drifted from this Go struct. This is a schema-contract mismatch, not a data problem.

Source

Thrown at internal/storage/v1/cassandra/spanstore/dbmodel/cql_udt.go:49

// MarshalUDT handles marshalling a Tag.
func (t *KeyValue) MarshalUDT(name string, info gocql.TypeInfo) ([]byte, error) {
	switch name {
	case "key":
		return gocql.Marshal(info, t.Key)
	case "value_type":
		return gocql.Marshal(info, t.ValueType)
	case "value_string":
		return gocql.Marshal(info, t.ValueString)
	case "value_bool":
		return gocql.Marshal(info, t.ValueBool)
	case "value_long":
		return gocql.Marshal(info, t.ValueInt64)
	case "value_double":
		return gocql.Marshal(info, t.ValueFloat64)
	case "value_binary":
		return gocql.Marshal(info, t.ValueBinary)
	default:
		return nil, fmt.Errorf("unknown column for position: %q", name)
	}
}

// UnmarshalUDT handles unmarshalling a Tag.
func (t *KeyValue) UnmarshalUDT(name string, info gocql.TypeInfo, data []byte) error {
	switch name {
	case "key":
		return gocql.Unmarshal(info, data, &t.Key)
	case "value_type":
		return gocql.Unmarshal(info, data, &t.ValueType)
	case "value_string":
		return gocql.Unmarshal(info, data, &t.ValueString)
	case "value_bool":
		return gocql.Unmarshal(info, data, &t.ValueBool)
	case "value_long":
		return gocql.Unmarshal(info, data, &t.ValueInt64)
	case "value_double":
		return gocql.Unmarshal(info, data, &t.ValueFloat64)

View on GitHub (pinned to 806f444784)

Solutions

  1. Compare the tags UDT definition (DESCRIBE keyspace / system_schema.usertypes) against the case names in cql_udt.go and re-apply the canonical Jaeger schema (migrations from plugin/storage/cassandra).
  2. Remove or rename any custom/stray columns added to the UDT; Cassandra UDTs cannot DROP fields, so recreate the UDT/table if drifted.
  3. Ensure the Jaeger binary and the schema version were provisioned from the same release.

Example fix

// before (cqlsh, drifted UDT)
ALTER TYPE tags ADD extra_field text;
// after
-- recreate UDT with exactly the fields dbmodel.KeyValue marshals:
-- tag_key, tag_type, value_string, value_bool, value_int64, value_double, value_binary
CREATE TYPE tags (...);
Defensive patterns

Strategy: validation

Validate before calling

// Run before deploying: compare UDT fields in Cassandra with expected ones
SELECT keyspace_name, type_name, field_names
FROM system_schema.usertypes
WHERE type_name IN ('tag','log','span_ref','process');
// tag must be exactly: tag_key, tag_type, value_string, value_bool, value_int64, value_double, value_binary

Prevention

When it happens

Trigger: Writing spans when the tags UDT in Cassandra contains a column not present in the dbmodel.KeyValue switch — e.g. a manually added column, a UDT created by a different Jaeger/schema version, or a typo'd column name in cqlsh DDL.

Common situations: Running a newer Jaeger against an old schema (or vice versa); custom ALTER TYPE additions to the UDT; restoring data into a keyspace whose UDTs were re-created with different field names.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/2d72c3f6fa93e1b2. Report an issue: GitHub.