Skip to content

A read that fails partway through a response exits 1, not 8 #146

Closed

Description

@tamnd

Exit 8 says the bytes did not arrive, and a supervisor is told to back off and try again on it. It only fires for a request that never got an answer, because that is the one place ErrTransport is attached: the retry loop in ccrawl/client.go. A read that fails partway through a response body has already got its answer, so it comes back as whatever the network handed over, unclassified, and classify in cli/classify.go leaves it as exit 1.

Caught live while timing a rank lookup:

$ time ccrawl rank host no-such-host-anywhere.invalid; echo $?
Read tcp [2001:ee0:...]:54947->[2600:9000:...]:443: read: no route to host.

real	1m17.585s
1

That is exit 1, the code the reference reserves for "the command itself is wrong". Nothing was wrong with the command. The route went away 77 seconds into a stream.

It hits the long commands hardest, which is where it matters most: the rank table is 262 million rows, the edge files are 7.7 GB, and a columnar scan is bigger still. Those are exactly the runs a supervisor is meant to restart, and exactly the runs most likely to lose a connection partway through, because they hold one open for minutes.

The documented supervisor pattern in the exit codes page stops on this rather than retrying:

case $? in
  8) sleep 3600; exec "$0" "$@" ;;
  *) exit 1 ;;
esac

Done when

  • a read error partway through a body exits 8
  • a status the server sent still exits 1, so 503 does not become retry forever
  • the classification happens somewhere every command goes through, not per command

Activity

  1. added this to the v0.10.1 milestone on Aug 12, 2026
  2. tamnd commented on Aug 13, 2026

    @tamnd
    OwnerAuthor

    The fix caught the real thing today, on the failure it was written for rather than a constructed one.

    ccrawl host enrich www.facebook.com --degrees streaming the web graph vertex table:

    {"ts":"2026-08-12T23:53:08.127Z","event":"start","pipeline":"host enrich"}
    {"ts":"2026-08-13T00:06:28.800Z","event":"end","phase":"vertices","elapsed_s":800.670773084}
    
      Phase 2 vertices: read tcp [2001:ee0:40e1:...]:60647->[2600:9000:26cc:...]:443: read: no route to host.
    
    exit 8
    

    800 seconds of streaming, ended by the network, exit 8. Before #147 that was exit 1 and a supervisor would have stopped on it rather than backing off and running it again, which is the right thing to do with a thirteen-minute read that died on the wire.

    Same run, same shape, same wrong exit code as the rank host capture in the issue. Nothing was staged for this: the run was started to measure something else and failed on its own.

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

    area: transportHTTP client, S3, rate limitingtype: bugSomething is wrong

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions