vxcontrol/pentagi · error
failed to force flush tracer: %w
Error message
failed to force flush tracer: %w
What it means
This error is produced by telemetryClient.ForceFlush when the trace provider fails to force-flush pending spans. It is wrapped with context naming the tracer leg, joined with any logger/meter flush errors via errors.Join.
Source
Thrown at backend/pkg/observability/otelclient.go:93
}
// Always close the connection, even if a provider shutdown failed above, so a
// stalled flush can't leak the grpc conn.
if err := c.conn.Close(); err != nil {
errs = append(errs, fmt.Errorf("failed to close telemetry connection: %w", err))
}
return errors.Join(errs...)
}
func (c *telemetryClient) ForceFlush(ctx context.Context) error {
var errs []error
if err := c.logger.ForceFlush(ctx); err != nil {
errs = append(errs, fmt.Errorf("failed to force flush logger: %w", err))
}
if err := c.meter.ForceFlush(ctx); err != nil {
errs = append(errs, fmt.Errorf("failed to force flush meter: %w", err))
}
if err := c.tracer.ForceFlush(ctx); err != nil {
errs = append(errs, fmt.Errorf("failed to force flush tracer: %w", err))
}
return errors.Join(errs...)
}
func NewTelemetryClient(ctx context.Context, cfg *config.Config) (TelemetryClient, error) {
if cfg.TelemetryEndpoint == "" {
return nil, fmt.Errorf("telemetry endpoint is not set: %w", ErrNotConfigured)
}
// grpc.NewClient is non-blocking: it never dials during startup, so a
// set-but-unreachable collector can't stall main(), and the connection is
// established (and re-established) lazily in the background — a collector that
// comes up after the app does connects on its own, without a restart.
conn, err := grpc.NewClient(
cfg.TelemetryEndpoint,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithDefaultCallOptions(grpc.WaitForReady(true)),
)View on GitHub (pinned to ea665308ba)
Solutions
- Read the joined/wrapped cause for the real exporter error
- Verify collector reachability at cfg.TelemetryEndpoint (port 4317)
- Use a longer-lived context for shutdown flushes
- Treat as non-fatal at shutdown: log and continue, since spans are typically advisory
Defensive patterns
Strategy: try-catch
Validate before calling
if client == nil { return } // telemetry never initialized Try / catch
if err := client.ForceFlush(ctx); err != nil {
log.Warnf("span flush failed (spans may be dropped): %v", err)
} Prevention
- Flush with a fresh, long-enough context at shutdown
- Keep the collector within the same network namespace where possible
- Avoid canceling the parent context mid-flush
- Consider a bounded retry for tracer flush
When it happens
Trigger: Calling ForceFlush(ctx) while otlptracegrpc cannot export buffered spans: ctx deadline exceeded, collector unavailable, exporter returning a retryable/permanent export error.
Common situations: Graceful shutdown with a down or overloaded OpenTelemetry Collector; spans accumulated during a burst exceeding the flush timeout; DNS/network failures to the telemetry endpoint.
Related errors
- failed to force flush logger: %w
- failed to force flush meter: %w
- failed to create tracer exporter: %w
- failed to create telemetry connection: %w
- failed to create log exporter: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/0b888e14574b1c62.
Report an issue: GitHub.