{"record":{"id":"312580090d2f3078","repo":"neondatabase/neon","slug":"cannot-find-blkno","errorCode":null,"errorMessage":"cannot find 'blkno='","messagePattern":"cannot find 'blkno='","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pageserver/ctl/src/key.rs","lineNumber":259,"sourceCode":"}\n\n#[derive(Debug)]\npub(super) struct SpanAttributesFromLogs(RelTag, BlockNumber);\n\nimpl std::str::FromStr for SpanAttributesFromLogs {\n    type Err = anyhow::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        // accept the span separator but do not require or fail if either is missing\n        // \"whatever{rel=1663/16389/24615 blkno=1052204 req_lsn=FFFFFFFF/FFFFFFFF}\"\n        let (_, reltag) = s\n            .split_once(\"rel=\")\n            .ok_or_else(|| anyhow::anyhow!(\"cannot find 'rel='\"))?;\n        let reltag = reltag.split_whitespace().next().unwrap();\n\n        let (_, blocknum) = s\n            .split_once(\"blkno=\")\n            .ok_or_else(|| anyhow::anyhow!(\"cannot find 'blkno='\"))?;\n        let blocknum = blocknum.split_whitespace().next().unwrap();\n\n        let reltag = reltag\n            .parse()\n            .with_context(|| format!(\"parse reltag from {reltag:?}\"))?;\n        let blocknum = blocknum\n            .parse()\n            .with_context(|| format!(\"parse blocknum from {blocknum:?}\"))?;\n\n        Ok(Self(reltag, blocknum))\n    }\n}\n\n#[derive(Debug)]\n#[allow(dead_code)] // debug print is used\nenum RecognizedKeyKind {\n    DbDir,\n    ControlFile,","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/neondatabase/neon/blob/8f60b04da47ffefe0e52bda2440134b42874eb75/pageserver/ctl/src/key.rs#L241-L277","documentation":"SpanAttributesFromLogs::from_str requires both markers in the pasted log line: rel= (checked first) and blkno=. After rel= is found, a missing blkno= marker fails the parse. Like error 213, this also surfaces nested inside error 210's combined message.","triggerScenarios":"Passing a log line that contains rel=... but no blkno= marker, so no block number can be extracted.","commonSituations":"Pasting relation-only log lines; log levels or code paths that omit the block number attribute; trimmed log output.","solutions":["Use a log line that also contains blkno=<number>, for example blkno=1052204.","If the block number is known separately, use the multi-argument form: pageserver_ctl key 1663/16389/24615 1052204."],"exampleFix":"# before\npageserver_ctl key \"whatever{rel=1663/16389/24615}\"\n# -> \"cannot find 'blkno='\"\n\n# after\npageserver_ctl key \"whatever{rel=1663/16389/24615 blkno=1052204}\"","handlingStrategy":"validation","validationCode":"// both markers are required for the single-argument log-line form\nanyhow::ensure!(\n    line.contains(\"rel=\") && line.contains(\"blkno=\"),\n    \"log line must contain both rel= and blkno=\"\n);","typeGuard":"fn log_line_parseable(line: &str) -> bool {\n    line.contains(\"rel=\") && line.contains(\"blkno=\")\n}","tryCatchPattern":null,"preventionTips":["Check for both rel= and blkno= before pasting a log line as a single argument.","Fall back to the multi-argument form when the line is missing either marker."],"tags":["rust","neon","ctl","key-parsing","log-parsing"],"backgroundTag":"log-line-parse-failed","analyzedSha":"8f60b04da47ffefe0e52bda2440134b42874eb75","analyzedAt":"2026-08-16T23:39:28.135Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}