rustfs/rustfs · error · GlobalError
Telemetry initialization failed: {0}
Error message
Telemetry initialization failed: {0} What it means
GlobalError::TelemetryError(#[from] TelemetryError) is the transparent wrapper for the whole TelemetryError enum (crates/obs/src/error.rs:51). It surfaces whenever telemetry initialization fails: exporter construction (BuildSpanExporter/BuildMetricExporter/BuildLogExporter), recorder installation (InstallMetricsRecorder), subscriber setup (SubscriberInit), I/O (Io), log-file permissions (SetPermissions), or stdout conflicts (LogSinkConflict). The inner variant is the real diagnosis; treat this variant as a router.
Source
Thrown at crates/obs/src/error.rs:51
#[error("Global guard lock poisoned: {0}")]
GuardPoisoned(&'static str),
#[error("Global system metrics err: {0}")]
MetricsError(String),
#[error("Failed to get current PID: {0}")]
PidError(String),
#[error("Process with PID {0} not found")]
ProcessNotFound(u32),
#[error("Failed to get physical core count")]
CoreCountError,
#[error("GPU initialization failed: {0}")]
GpuInitError(String),
#[error("GPU device not found: {0}")]
GpuDeviceError(String),
#[error("Failed to send log: {0}")]
SendFailed(&'static str),
#[error("Operation timed out: {0}")]
Timeout(&'static str),
#[error("Telemetry initialization failed: {0}")]
TelemetryError(#[from] TelemetryError),
}
#[derive(Debug, thiserror::Error)]
pub enum TelemetryError {
#[error("Span exporter build failed: {0}")]
BuildSpanExporter(String),
#[error("Metric exporter build failed: {0}")]
BuildMetricExporter(String),
#[error("Log exporter build failed: {0}")]
BuildLogExporter(String),
#[error("Install metrics recorder failed: {0}")]
InstallMetricsRecorder(String),
#[error("Tracing subscriber init failed: {0}")]
SubscriberInit(String),
#[error("I/O error: {0}")]
Io(String),
#[error("Set permissions failed: {0}")]View on GitHub (pinned to 35af688cd9)
Solutions
- Match on the inner TelemetryError variant first — each variant maps to a distinct fix (see the sibling entries)
- Validate the telemetry config (endpoint URL, log directory writability, sink exclusivity) before init
- Fail fast at startup: do not ignore this error and continue with telemetry silently absent
Example fix
// before
let result = obs::init_telemetry(&cfg);
if result.is_err() { /* opaque handling */ }
// after
match obs::init_telemetry(&cfg) {
Ok(()) => {}
Err(GlobalError::TelemetryError(TelemetryError::BuildSpanExporter(e))) => {
return Err(format!("OTLP span endpoint invalid: {e}"));
}
Err(other) => return Err(other.to_string()),
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the pieces init depends on before calling it:
fn telemetry_config_sane(cfg: &ObsConfig) -> Result<(), String> {
if let Some(ep) = &cfg.otlp_endpoint {
url::Url::parse(ep).map_err(|e| format!("bad OTLP endpoint: {e}"))?;
}
if let Some(dir) = &cfg.log_directory {
std::fs::create_dir_all(dir).map_err(|e| format!("log dir unusable: {e}"))?;
}
Ok(())
} Type guard
fn is_telemetry_init_err(e: &GlobalError) -> bool {
matches!(e, GlobalError::TelemetryError(_))
} Try / catch
match obs::init_telemetry(&cfg) {
Ok(()) => Ok(()),
Err(GlobalError::TelemetryError(inner)) => match inner {
TelemetryError::BuildSpanExporter(m)
| TelemetryError::BuildMetricExporter(m)
| TelemetryError::BuildLogExporter(m) => Err(format!("fix OTLP config: {m}")),
TelemetryError::SetPermissions(m) => Err(format!("fix log dir ownership: {m}")),
other => Err(other.to_string()),
},
Err(e) => Err(e.to_string()),
} Prevention
- Validate endpoint URLs and log-directory writability before init; each maps to a distinct inner variant
- Fail fast on telemetry init errors in server binaries — silent absence costs more later
- Learn the inner-variant map: exporter builds -> endpoint config, SetPermissions -> filesystem, LogSinkConflict -> stdout ownership
When it happens
Trigger: Calling the telemetry init API (otel.rs / local.rs init paths) with a config that fails at any stage — bad OTLP endpoint, unwritable log directory, conflicting stdout sink, or a double recorder install.
Common situations: Fresh deployments with unvalidated endpoint URLs; log_directory on read-only mounts or with wrong ownership; running the binary with stdout already captured in a way the local sink rejects; feature flags mismatch on exporters.
Related errors
- shard read abandoned after read quorum
- shard read hedged after a slow shard
- Failed to set a global recorder: {0}
- Failed to set global guard: {0}
- Global guard not initialized
AI-assisted analysis of rustfs/rustfs@35af688cd9 (2026-08-20).
Data as JSON: /api/errors/69e4e786fd45263a.
Report an issue: GitHub.