weaviate/weaviate · error

write individual node (res2.primaryKey smaller): %w

Error message

write individual node (res2.primaryKey smaller): %w

What it means

Symmetric counterpart of the res1-smaller case: when segment 2's key is the smaller one, res2's node is written via writeIndividualNode (skipped if tombstone-cleanup applies and err2 is Deleted). This error wraps any failure of that node write — I/O error on the buffered writer, value transformation failure, or secondary-index write failure.

Source

Thrown at adapters/repos/db/lsmkv/compactor_replace.go:230

			if !(c.cleanupTombstones && errors.Is(err1, lsmkv.Deleted)) {
				ki, err := c.writeIndividualNode(f, offset, res1.primaryKey, res1.value,
					res1.secondaryKeys, errors.Is(err1, lsmkv.Deleted))
				if err != nil {
					return nil, fmt.Errorf("write individual node (res1.primaryKey smaller): %w", err)
				}

				offset = ki.ValueEnd
				c.accumulateIndexSizes(ki)
				kis = append(kis, ki)
			}
			res1, err1 = c.c1.next()
		} else {
			// key 2 is smaller
			if !(c.cleanupTombstones && errors.Is(err2, lsmkv.Deleted)) {
				ki, err := c.writeIndividualNode(f, offset, res2.primaryKey, res2.value,
					res2.secondaryKeys, errors.Is(err2, lsmkv.Deleted))
				if err != nil {
					return nil, fmt.Errorf("write individual node (res2.primaryKey smaller): %w", err)
				}

				offset = ki.ValueEnd
				c.accumulateIndexSizes(ki)
				kis = append(kis, ki)
			}
			res2, err2 = c.c2.next()
		}
	}

	return kis, nil
}

// TREE_KEY_STORE_OVERHEAD + len(key) is the overhead of storing a key in the index:
//   - 4 bytes for the length of the key
//   - len(key) bytes for the key itself
//   - 8 bytes for the node start pos (points to matching file offset in the Strategy specific data structure)
//   - 8 bytes for the node end pos (points to matching file offset in the Strategy specific data structure)

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Check the wrapped cause and address it (ENOSPC -> expand disk; transform error -> inspect values).
  2. Re-trigger compaction after fixing storage.
  3. Rebuild the bucket from backup if the same segment repeatedly fails.
  4. File a bug with logs if transformation fails on regular values.
Defensive patterns

Strategy: try-catch

Try / catch

if err := bucket.Compact(ctx); err != nil {
	if strings.Contains(err.Error(), "write individual node") {
		// resolve underlying cause (disk/transform) then re-trigger
		scheduleCompactionRetry(bucket)
	}
}

Prevention

When it happens

Trigger: Segment 2 holds the smallest current key and writeIndividualNode fails: disk full/EIO, valueTransformer error on the live value, or secondary index serialization error.

Common situations: Disk exhaustion during compaction; storage device failure; transformer incompatibility with values written by an older segment version.

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/f553a73d08fd2353. Report an issue: GitHub.