jaegertracing/jaeger · error

failed to scan dependency row: %w

Error message

failed to scan dependency row: %w

What it means

While iterating result rows in GetDependencies, each row holds a JSON blob of dependency links that is scanned into a string. If rows.Scan fails — a NULL, an unexpected column type, or driver-level decode error — the error is wrapped with this message and returned, aborting dependency retrieval. It indicates the stored data or schema deviates from what the reader expects, not a transient fault.

Source

Thrown at internal/storage/v2/clickhouse/depstore/reader.go:47

type dependencyKey struct {
	parent string
	child  string
}

func (r *Reader) GetDependencies(ctx context.Context, query depstore.QueryParameters) ([]model.DependencyLink, error) {
	rows, err := r.conn.Query(ctx, sql.SelectDependencies, query.StartTime, query.EndTime)
	if err != nil {
		return nil, fmt.Errorf("failed to query dependencies: %w", err)
	}
	defer rows.Close()

	// Merge dependencies from all snapshots in the time range.
	merged := make(map[dependencyKey]uint64)

	for rows.Next() {
		var blob string
		if err := rows.Scan(&blob); err != nil {
			return nil, fmt.Errorf("failed to scan dependency row: %w", err)
		}
		var links []dependencyLink
		if err := json.Unmarshal([]byte(blob), &links); err != nil {
			return nil, fmt.Errorf("failed to unmarshal dependencies JSON: %w", err)
		}
		for _, link := range links {
			merged[dependencyKey{link.Parent, link.Child}] += link.CallCount
		}
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("failed to read dependency rows: %w", err)
	}

	if len(merged) == 0 {
		return nil, nil
	}

	dependencies := make([]model.DependencyLink, 0, len(merged))

View on GitHub (pinned to 806f444784)

Solutions

  1. Verify the ClickHouse schema matches the expected jaeger_dependencies layout (dependencies column is a non-nullable String).
  2. Re-run schema initialization/migration and inspect offending rows; repair or delete corrupted snapshots.
  3. Unwrap with errors.As to the clickhouse-go error type to confirm the scan/decode cause before changing data.

Example fix

// schema before
dependencies Nullable(String)
// after
dependencies String CODEC(ZSTD(1))
Defensive patterns

Strategy: try-catch

Validate before calling

// check schema expectations before querying
rows, err := conn.Query(ctx, "SELECT name, type FROM system.columns WHERE table = 'jaeger_dependencies'")
// verify a non-nullable String dependencies column exists

Try / catch

deps, err := reader.GetDependencies(ctx, q)
if err != nil {
  if strings.Contains(err.Error(), "failed to scan dependency row") {
    log.Printf("schema or data corruption suspected: %v", err) // trigger schema repair/verification
  }
  return err
}

Prevention

When it happens

Trigger: GetDependencies iterating rows where rows.Scan(&blob) fails: the dependencies column is NULL or of an unexpected type (e.g. non-String due to a schema change), or the driver fails to decode the value into a string.

Common situations: Schema drift after upgrading Jaeger or running an older ClickHouse schema against newer code; manual table edits leaving NULL blobs; corrupted snapshot rows from an interrupted write; wrong database/table pointed at by config.

Related errors


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