openai/codex · error · io::Error
network proxy attribution token is not UTF-8
Error message
network proxy attribution token is not UTF-8
What it means
The declared number of token bytes was read successfully but is not valid UTF-8; the ingress requires the attribution token to be a UTF-8 string and rejects with InvalidData. The shipped writer takes &str, so this only happens with hand-built frames: a binary token (raw hash/UUID bytes) or a length prefix that is off, causing framing bytes to be swallowed into the token field.
Source
Thrown at codex-rs/network-proxy/src/attribution.rs:104
stream.read_exact(&mut magic).await?;
if &magic != ATTRIBUTION_FRAME_MAGIC {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"invalid network proxy attribution frame",
));
}
let token_len = stream.read_u16().await? as usize;
if token_len == 0 || token_len > MAX_ATTRIBUTION_TOKEN_LEN {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"invalid network proxy attribution token length",
));
}
let mut token = vec![0_u8; token_len];
stream.read_exact(&mut token).await?;
String::from_utf8(token).map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidData,
"network proxy attribution token is not UTF-8",
)
})
})
.await
.map_err(|_| {
io::Error::new(
io::ErrorKind::TimedOut,
"network proxy attribution frame timed out",
)
})??;
Ok(Some(token))
}
/// Writes the trusted bridge preface consumed by the shared proxy ingress.
#[doc(hidden)]View on GitHub (pinned to 339751715c)
Solutions
- Pass a UTF-8 string token -- hex- or base64-encode binary ids first.
- Recompute token_len as exactly token.as_bytes().len() with no header bytes included.
- Use write_attribution_frame, whose &str parameter rules non-UTF-8 tokens out by construction.
Example fix
// before: raw binary id used as the token let token: &[u8] = uuid.as_bytes(); // may be non-UTF-8 // after: textual encoding let token = uuid.to_string(); // ASCII hyphenated form
Defensive patterns
Strategy: validation
Validate before calling
// Reject before writing the frame when building bytes yourself
if std::str::from_utf8(token_bytes).is_err() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"attribution token must be valid UTF-8",
));
} Type guard
fn is_utf8_token(bytes: &[u8]) -> bool {
std::str::from_utf8(bytes).is_ok()
} Try / catch
Match io::ErrorKind::InvalidData whose message contains 'not UTF-8': re-encode the token as hex/base64 and recompute token_len; if the token was textual, the length prefix is off -- audit the framing arithmetic.
Prevention
- Keep tokens textual (hex or base64 for binary ids).
- Set token_len = token.as_bytes().len() exactly, with no header bytes.
- Prefer the &str-taking write_attribution_frame helper, which cannot emit non-UTF-8 tokens.
When it happens
Trigger: A custom writer puts raw binary (16-byte UUID, SHA digest) into the token field; token_len is off by the header size so read_exact consumes part of the next field; deliberate fuzz/malformed input after a correct magic.
Common situations: Porting the preface to another language and passing bytes instead of str; length arithmetic that accidentally includes the magic or length fields in token_len.
Related errors
- invalid network proxy attribution frame
- invalid network proxy attribution token length
- I/O error while reading memories: {0}
- unknown network proxy attribution token
- network proxy attribution environment mismatch
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/d5db8887f1621c79.
Report an issue: GitHub.