neondatabase/neon · error
found no RelTag in arguments
Error message
found no RelTag in arguments
What it means
With two or more positional arguments, the key subcommand scans left to right for the first argument that parses as a RelTag (after stripping an optional rel= prefix). A RelTag looks like 1663/16389/24615 (tablespace/OID/database, optionally with a fork number). If no argument parses as a RelTag, the command bails.
Source
Thrown at pageserver/ctl/src/key.rs:219
more => {
// assume going left to right one of these is a reltag and then we find a blocknum
// this works, because we don't have plain numbers at least right after reltag in
// logs. for some definition of "works".
let Some((reltag_at, reltag)) = more
.iter()
.map(AsRef::as_ref)
.enumerate()
.find_map(|(i, s)| {
s.split_once("rel=")
.map(|(_garbage, actual)| actual)
.unwrap_or(s)
.parse::<RelTag>()
.ok()
.map(|rt| (i, rt))
})
else {
anyhow::bail!("found no RelTag in arguments");
};
let Some(blocknum) = more
.iter()
.map(AsRef::as_ref)
.skip(reltag_at)
.find_map(|s| {
s.split_once("blkno=")
.map(|(_garbage, actual)| actual)
.unwrap_or(s)
.parse::<BlockNumber>()
.ok()
})
else {
anyhow::bail!("found no blocknum in arguments");
};
Ok(KeyMaterial::Split(reltag, blocknum))View on GitHub (pinned to 8f60b04da4)
Solutions
- Include the reltag as one argument, for example 1663/16389/24615 or rel=1663/16389/24615.
- When copy-pasting from logs, keep the rel=... token intact; the parser strips the prefix itself.
Example fix
# before pageserver_ctl key 1052204 FFFF/FFFFFFFF # -> "found no RelTag in arguments" # after pageserver_ctl key 1663/16389/24615 1052204
Defensive patterns
Strategy: validation
Validate before calling
// ensure at least one argument parses as a RelTag (with optional rel= prefix)
let has_reltag = args.iter().any(|s| {
s.split_once("rel=").map(|(_, v)| v).unwrap_or(s).parse::<RelTag>().is_ok()
});
anyhow::ensure!(has_reltag, "no argument parses as a RelTag like 1663/16389/24615"); Type guard
fn contains_reltag(args: &[String]) -> bool {
args.iter().any(|s| {
s.split_once("rel=").map(|(_, v)| v).unwrap_or(s).parse::<RelTag>().is_ok()
})
} Prevention
- Keep the rel=... token intact when copying from logs; the parser strips the prefix itself.
- Pass the reltag as its own whitespace-separated argument.
When it happens
Trigger: Multiple arguments where no element is a valid RelTag: only a block number and an LSN, or a reltag with non-numeric or missing components.
Common situations: Splitting a log line on whitespace and losing the rel= token; reltags with an unexpected fork suffix; hand-typed arguments with typos.
Related errors
- need 1..N positional arguments describing the key, try hex o
- failed to parse {one:?} as hex or span attributes: - {e1:#}
- found no blocknum in arguments
- cannot find 'rel='
- cannot find 'blkno='
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/3e78f56b275bfd97.
Report an issue: GitHub.