openzipkin/zipkin · error · Error

Trace ${traceId} is missing a timestamp

Error message

Trace ${traceId} is missing a timestamp

What it means

Thrown by zipkin-lens's trace summarizer (TreeBuilder→traceSummary path) when, after traversing every span in the tree, not a single span carried a timestamp. Span timestamps anchor the trace timeline; without at least one, the UI cannot compute a root timestamp, duration, or draw the trace waterfall.

Source

Thrown at zipkin-lens/src/zipkin/trace.js:74

// Returns null on empty or when missing a timestamp
export function traceSummary(root) {
  const timestamps = [];
  const groupedTimestamps = {};

  let traceId;
  let spanCount = 0;
  let errorType = 'none';

  root.traverse((span) => {
    spanCount += 1;
    traceId = span.traceId;
    errorType = getErrorType(span, errorType);
    addTimestamps(span, timestamps);
    addServiceNameTimestampDuration(span, groupedTimestamps);
  });

  if (timestamps.length === 0)
    throw new Error(`Trace ${traceId} is missing a timestamp`);

  // If the first element does not exist, Error will be thrown.
  // So we don't have to check rootSpan exisitence.
  const [rootSpan] = root.queueRootMostSpans();
  const rootServiceName =
    getServiceName(rootSpan._span.localEndpoint) ||
    getServiceName(rootSpan._span.remoteEndpoint) ||
    'unknown';
  const rootSpanName = rootSpan._span.name || 'unknown';

  return {
    traceId,
    timestamp: timestamps[0],
    duration: getMaxDuration(timestamps),
    groupedTimestamps,
    errorType,
    spanCount,
    root: {

View on GitHub (pinned to 878ce2a1fa)

Solutions

  1. Ensure at least one span in each trace has a numeric timestamp (microseconds since epoch); normally every RPC span should have one.
  2. Fix the reporting pipeline if timestamps are being dropped (check serialization, size limits, field renaming).
  3. When constructing spans manually in tests, always set timestamp and duration.

Example fix

// before
const spans = [{ traceId: 'a', id: 'a', name: 'root' }]; // no timestamp anywhere
traceSummary(spans); // throws 'Trace ... is missing a timestamp'

// after
const spans = [{ traceId: 'a', id: 'a', name: 'root', timestamp: 1700000000000000, duration: 1000 }];
traceSummary(spans);
Defensive patterns

Strategy: validation

Validate before calling

if (!spans.some((s) => typeof s.timestamp === 'number')) throw new Error('trace has no span with a timestamp');

Type guard

const hasTimestamp = (spans) => spans.some((s) => typeof s?.timestamp === 'number');

Prevention

When it happens

Trigger: Building a trace summary from a span list where every span has timestamp undefined/null — e.g. client-reported spans that were never server-adjusted, or spans stripped of timestamps by instrumentation that only sets ids and names.

Common situations: Test fixtures with spans missing the timestamp field; async/local spans reported with no timestamp; data mangled by a proxy or serializer dropping numeric fields; spans from a tracer that defers clock capture and crashed before setting it.

Related errors


AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14). Data as JSON: /api/errors/5b710e3083a26638. Report an issue: GitHub.