Skip to content

get_payload returns InternalServerError ~5.1k/day with no diagnostic log #541

Description

@0w3n-d

What's wrong

get_payload returns InternalServerError to proposers about 5,127 times a
day, and the relay logs no reason for any of them.

The 5,127 figure comes from the #[tracing::instrument(..., err)] event on
api/proposer/get_payload.rs:137/:210, which reports
error=internal server error with the request id and slot and nothing else.
Measured on titan_relay.log.2026-08-30 (mainnet,
relay-mainnet-1-aws-fr). For comparison, on the same day the explicit error
logs on that path — failed sending request to worker (:297), failed to receive payload response from auctioneer (:316), timed out waiting for payload response from auctioneer (:321) — fired zero times.

So the 500s are being produced somewhere that logs nothing, and we cannot tell
from the logs whether a proposer lost a block because of us.

The same instrument(err) event also reports these ordinary client
conditions, which are expected and are covered by the logging cleanup issue,
not by this one: request for past slot (4,109), proposer not registered
(1,331), no execution payload for this request (941), duplicate payload request (57), already delivering payload (38).

Repro

Not yet known — identifying the path is Step 1.

Suspected cause

ProposerApiError::InternalServerError is returned from several places on the
get_payload path. The three that log are silent in production, so the
returns that fire must be the ones without a log line. Enumerating the
variants that map to Display = internal server error will narrow it.

Affected surface

crates/relay/src/api/proposer/get_payload.rs,
crates/relay/src/api/proposer/error.rs.

Steps (each becomes one PR)

  • Step 1: Audit every path returning ProposerApiError::InternalServerError from get_payload, and give each a distinct log or a distinct error variant so the cause is identifiable from the logs. (tests: unit test per newly distinguished variant) (PR: )
  • Step 2: Once the dominant cause is known, fix it. Scope to be set by Step 1's findings. (tests: ) (PR: )

Open questions

Do any of these 5,127 coincide with a missed slot? Cross-referencing against
delivered-payload records would say whether this is a cosmetic 500 after the
payload was already delivered, or a real delivery failure.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions