{"record":{"id":"605edc3980209dd1","repo":"rustfs/rustfs","slug":"rustfs-is-not-registered-with-connect-605edc","errorCode":null,"errorMessage":"RustFS is not registered with Connect","messagePattern":"RustFS is not registered with Connect","errorType":"exception","errorClass":"HeartbeatError","httpStatus":null,"severity":"warning","filePath":"rustfs/src/connect/heartbeat.rs","lineNumber":369,"sourceCode":"}\n\nfn fsync_dir(directory: &Path) -> io::Result<()> {\n    #[cfg(unix)]\n    fs::File::open(directory)?.sync_all()?;\n    #[cfg(not(unix))]\n    let _ = directory;\n    Ok(())\n}\n\n#[derive(Debug, thiserror::Error)]\npub enum HeartbeatError {\n    #[error(\"Connect heartbeat endpoint must be an HTTPS base URL without credentials, query, or fragment\")]\n    Endpoint,\n    #[error(\"Connect heartbeat root CA configuration is invalid\")]\n    RootCertificate,\n    #[error(\"Connect heartbeat schedule is invalid\")]\n    Schedule,\n    #[error(\"RustFS is not registered with Connect\")]\n    NotRegistered,\n    #[error(\"the Connect device private key is missing\")]\n    IdentityMissing,\n    #[error(\"the stored Connect certificate and device private key cannot form a TLS identity\")]\n    IdentityCertificate,\n    #[error(\"the stored Connect credential name is invalid\")]\n    CredentialName,\n    #[error(\"the stored Connect device certificate is not currently valid\")]\n    CredentialExpired,\n    #[error(\"the Connect heartbeat node summary is outside protocol bounds\")]\n    NodeSummary,\n    #[error(\"the Connect heartbeat sequence is exhausted\")]\n    SequenceExhausted,\n    #[error(\"a Connect heartbeat runtime already owns this state\")]\n    AlreadyRunning,\n    #[error(\"the persisted Connect heartbeat changed while delivery was in flight\")]\n    StateConflict,\n    #[error(\"Connect heartbeat state I/O failed at {path}: {source}\")]","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/rustfs/rustfs/blob/201c653dcd34c2a01b9aec5991ed76176b342118/rustfs/src/connect/heartbeat.rs#L351-L387","documentation":"Every heartbeat builds its mTLS client from a stored device credential; when credential_store.load() returns None (device.crt.json absent), the node has no Connect identity, so TelemetryError::NotRegistered maps to HeartbeatError::NotRegistered. It means registration never completed for this state directory — a pending registration file alone is not enough, the device credential only exists after completion. Heartbeats cannot proceed until registration finishes.","triggerScenarios":"Starting the heartbeat/telemetry loop on a fresh install before running Connect registration; registration started but interrupted before device.crt.json was written; the credential directory deleted, moved, or pointing at the wrong path (load() only treats NotFound as 'no credential').","commonSituations":"New deployments skipping onboarding; restoring cluster data without the connect state directory; containers losing the state volume on restart; env var typos pointing at an empty directory.","solutions":["Complete the Connect registration flow (token -> registration) so device.crt.json is persisted in the credential directory","Verify the credential directory is the same one registration wrote to and that device.crt.json exists with mode 0600","If registration was completed before, restore the state directory from backup; otherwise run registration again"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"let credential_file = Path::new(&connect_state_dir).join(\"device.crt.json\");\nif !credential_file.exists() {\n    // run Connect registration before starting the heartbeat loop\n}","typeGuard":"fn is_not_registered(err: &HeartbeatError) -> bool {\n    matches!(err, HeartbeatError::NotRegistered)\n}","tryCatchPattern":"match sender.send(&pending).await {\n    Err(HeartbeatError::NotRegistered) => {\n        // expected pre-registration: defer/suspend heartbeat, surface registration prompt;\n        // do NOT tight-loop retries — registration is an operator action\n    }\n    result => result,\n}","preventionTips":["Gate heartbeat startup on a completed registration check","Keep the connect state directory on a durable, backed-up volume","Monitor for the credential file's absence and alert before it matters"],"tags":["rust","rustfs","connect","registration","onboarding","heartbeat"],"backgroundTag":"device-not-registered","analyzedSha":"201c653dcd34c2a01b9aec5991ed76176b342118","analyzedAt":"2026-08-23T16:57:04.676Z","contentChangedAt":"2026-08-23T16:57:04.676Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}