FAILURE MAP
← Case archive

FA-30111 / HTTP retries / Open access

Failed response disposal and pool eligibility: Read closed violates retry transition semantics · case 01

Read closed violates retry transition semantics

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

Read closed violates retry transition semantics

VERIFIED REPAIR

Restore the specified transition if closed: out.append('closed'); continue.

Unsuccessful approach: The attempted repair changes the faulty site to if closed and remaining==0: out.append('closed'); continue but still violates a regression oracle.

Case contract

headers(length) opens failed response with remaining bytes; read(count) drains bounded content. eof confirms framing only if no bytes remain, otherwise poisons connection. close marks response closed; release returns pooled only for closed, fully drained, EOF-confirmed unpoisoned response. abort permanently poisons current connection. new resets all connection state. Return drain amounts and release disposition.

Why this case matters

Offline deterministic model of HTTP request retries.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(events):
    remaining=0; closed=True; eof=False; poison=False; out=[]
    for e in events:
        if e[0]=='new': remaining=0; closed=True; eof=False; poison=False
        elif e[0]=='headers':
            remaining=e[1]; closed=False; eof=False
        elif e[0]=='read':
            if closed: out.append(0); continue
            n=min(remaining,e[1]); remaining-=n; out.append(n)
        elif e[0]=='eof':
            if remaining!=0: poison=True
            else: eof=True
        elif e[0]=='close': closed=True
        elif e[0]=='abort': poison=True; closed=True
        elif e[0]=='release':
            if poison: out.append('discard')
            elif not closed: out.append('busy')
            elif remaining!=0: out.append('unread')
            elif not eof: out.append('unframed')
            else: out.append('pooled')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [])
check('1', solve([('headers',N+3),('read',2),('read',N+9),('eof',),('release',),('close',),('release',)]), [2,N+1,'busy','pooled'])
check('2', solve([('headers',1),('close',),('read',1),('release',)]), ['closed','unread'])
check('3', solve([('headers',1),('eof',),('read',1),('close',),('release',)]), [1,'discard'])
check('4', solve([('headers',0),('close',),('release',),('eof',),('release',)]), ['unframed','pooled'])
check('5', solve([('headers',0),('eof',),('abort',),('release',),('new',),('headers',0),('eof',),('close',),('release',)]), ['discard','pooled'])
check('6', solve([('headers',0),('eof',),('close',),('headers',0),('close',),('release',)]), ['unframed'])
check('7', solve([('headers',0),('read',1)]), [0])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
0[][]Passed
1[2, 2, 'busy', 'pooled'][2, 2, 'busy', 'pooled']Passed
2[0, 'unread']['closed', 'unread']Failed
3[1, 'discard'][1, 'discard']Passed
4['unframed', 'pooled']['unframed', 'pooled']Passed
5['discard', 'pooled']['discard', 'pooled']Passed
6['unframed']['unframed']Passed
7[0][0]Passed

SHA-256 / c170b3dfd43c355ab8fabfde4d14ab403f88c8ccbd8a0c422d73f893375b0b28

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(events):
    remaining=0; closed=True; eof=False; poison=False; out=[]
    for e in events:
        if e[0]=='new': remaining=0; closed=True; eof=False; poison=False
        elif e[0]=='headers':
            remaining=e[1]; closed=False; eof=False
        elif e[0]=='read':
            if closed and remaining==0: out.append('closed'); continue
            n=min(remaining,e[1]); remaining-=n; out.append(n)
        elif e[0]=='eof':
            if remaining!=0: poison=True
            else: eof=True
        elif e[0]=='close': closed=True
        elif e[0]=='abort': poison=True; closed=True
        elif e[0]=='release':
            if poison: out.append('discard')
            elif not closed: out.append('busy')
            elif remaining!=0: out.append('unread')
            elif not eof: out.append('unframed')
            else: out.append('pooled')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [])
check('1', solve([('headers',N+3),('read',2),('read',N+9),('eof',),('release',),('close',),('release',)]), [2,N+1,'busy','pooled'])
check('2', solve([('headers',1),('close',),('read',1),('release',)]), ['closed','unread'])
check('3', solve([('headers',1),('eof',),('read',1),('close',),('release',)]), [1,'discard'])
check('4', solve([('headers',0),('close',),('release',),('eof',),('release',)]), ['unframed','pooled'])
check('5', solve([('headers',0),('eof',),('abort',),('release',),('new',),('headers',0),('eof',),('close',),('release',)]), ['discard','pooled'])
check('6', solve([('headers',0),('eof',),('close',),('headers',0),('close',),('release',)]), ['unframed'])
check('7', solve([('headers',0),('read',1)]), [0])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
0[][]Passed
1[2, 2, 'busy', 'pooled'][2, 2, 'busy', 'pooled']Passed
2[1, 'unframed']['closed', 'unread']Failed
3[1, 'discard'][1, 'discard']Passed
4['unframed', 'pooled']['unframed', 'pooled']Passed
5['discard', 'pooled']['discard', 'pooled']Passed
6['unframed']['unframed']Passed
7[0][0]Passed

SHA-256 / f47773d3f21c999a769ed60c78ec75249a6a6ef99d6736bd18d946a7cef224e9

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(events):
    remaining=0; closed=True; eof=False; poison=False; out=[]
    for e in events:
        if e[0]=='new': remaining=0; closed=True; eof=False; poison=False
        elif e[0]=='headers':
            remaining=e[1]; closed=False; eof=False
        elif e[0]=='read':
            if closed: out.append('closed'); continue
            n=min(remaining,e[1]); remaining-=n; out.append(n)
        elif e[0]=='eof':
            if remaining!=0: poison=True
            else: eof=True
        elif e[0]=='close': closed=True
        elif e[0]=='abort': poison=True; closed=True
        elif e[0]=='release':
            if poison: out.append('discard')
            elif not closed: out.append('busy')
            elif remaining!=0: out.append('unread')
            elif not eof: out.append('unframed')
            else: out.append('pooled')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [])
check('1', solve([('headers',N+3),('read',2),('read',N+9),('eof',),('release',),('close',),('release',)]), [2,N+1,'busy','pooled'])
check('2', solve([('headers',1),('close',),('read',1),('release',)]), ['closed','unread'])
check('3', solve([('headers',1),('eof',),('read',1),('close',),('release',)]), [1,'discard'])
check('4', solve([('headers',0),('close',),('release',),('eof',),('release',)]), ['unframed','pooled'])
check('5', solve([('headers',0),('eof',),('abort',),('release',),('new',),('headers',0),('eof',),('close',),('release',)]), ['discard','pooled'])
check('6', solve([('headers',0),('eof',),('close',),('headers',0),('close',),('release',)]), ['unframed'])
check('7', solve([('headers',0),('read',1)]), [0])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
0[][]Passed
1[2, 2, 'busy', 'pooled'][2, 2, 'busy', 'pooled']Passed
2['closed', 'unread']['closed', 'unread']Passed
3[1, 'discard'][1, 'discard']Passed
4['unframed', 'pooled']['unframed', 'pooled']Passed
5['discard', 'pooled']['discard', 'pooled']Passed
6['unframed']['unframed']Passed
7[0][0]Passed

SHA-256 / 7d6ae0c23afde9e09b7faa67400ad79eb262c1a595982fa49c2174f34446fdd4

Verification & scope

Stipulated bounded simulator, not a complete HTTP implementation or a standards conformance claim. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:41:49.766796+00:00.

Case digest / c0dc3183ee044e9058646ede039c3667ec605a8aa08e18a8efb92204db0f0d76