Skip to content

REFUSED_STREAM surfaces as "Write error" instead of being retried #3112

Open

Description

@yashhshah

Problem description

This started happening on Node ≥ 24.22.0. Unary calls that are rejected with REFUSED_STREAM now fail with this error instead of being retried automatically:
14 UNAVAILABLE: Write error: Stream closed with error code NGHTTP2_REFUSED_STREAM

This appears to be caused by nodejs/node#66016. When a stream is destroyed, Node now passes the stream error to pending write callbacks. This change in behavior means grpc-js is treating the call as PROCESSED (instead of REFUSED) and skips the automatic retry.

Reproduction steps

I used a grpc-go health server with MaxConnectionAge: 100ms. The client ran 50 concurrent Health/Check calls for 8 seconds using @grpc/grpc-js 1.14.6:
Node v24.21.0: 365,762 successful calls, 0 failures
Node v24.22.1: 386,468 successful calls, 975 REFUSED_STREAM write errors

Additional context

I can put out a PR if you want. Node already sets the rstCode, so we probably just need to carry this info in grpc-js/src/subchannel-call.ts (at least thats what my robot is confirming)

Activity

  1. murgatroid99 commented on Oct 27, 2026

    @murgatroid99
    Member

    It looks like this will be fixed by #3111, if I understand the problem correctly.

  2. gunsch commented on Nov 5, 2026

    @gunsch
    Contributor

    FWIW, after upgrading to grpc-js@1.14.7 to pick up #3111, my team at reddit is still seeing the same failures as OP since our Node 24.22.0 upgrade:

    14 UNAVAILABLE: Write error: Stream closed with error code NGHTTP2_REFUSED_STREAM
    

    I'm working on further investigation but at a first pass that does not appear to have restored the automatic retries.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions