diff --git a/.github/scripts/docker_push_with_retry.sh b/.github/scripts/docker_push_with_retry.sh index 1518f882c6..628d538f46 100644 --- a/.github/scripts/docker_push_with_retry.sh +++ b/.github/scripts/docker_push_with_retry.sh @@ -34,7 +34,17 @@ set -euo pipefail # failures); a bare `tls: ` is intentionally NOT included because it would # also match non-transient configuration errors like # `tls: failed to verify certificate` or `tls: bad certificate`. -TRANSIENT_RE='page is taking too long|unknown blob|blob unknown|blob upload invalid|manifest unknown|received unexpected HTTP status: 5[0-9]{2}|HTTP/[0-9.]+ 5[0-9]{2}|HTTP 5[0-9]{2}|status: 5[0-9]{2}|429 Too Many Requests|temporarily unavailable|server is currently unable|service unavailable|bad gateway|gateway time-?out|i/o timeout|tls handshake|connection reset|connection refused|EOF|unexpected EOF|read: connection|net/http: TLS handshake' +# +# `context deadline exceeded` / `Client.Timeout exceeded` / `timeout awaiting +# response headers` / `timeout awaiting response body` / `request canceled` +# cover Go ``net/http`` client-side timeout strings emitted by Docker / buildx +# when GHCR fails to respond to a request within the per-request deadline. +# These are the canonical transient signatures `i/o timeout` misses on the +# GHCR HTTP path: the underlying socket may be healthy while the HTTP +# response just never arrives in time. Both the headers and body variants +# are kept so a stall after the upload starts streaming also retries -- +# `docker push` is idempotent, so re-pushing on a body-timeout is safe. +TRANSIENT_RE='page is taking too long|unknown blob|blob unknown|blob upload invalid|manifest unknown|received unexpected HTTP status: 5[0-9]{2}|HTTP/[0-9.]+ 5[0-9]{2}|HTTP 5[0-9]{2}|status: 5[0-9]{2}|429 Too Many Requests|temporarily unavailable|server is currently unable|service unavailable|bad gateway|gateway time-?out|i/o timeout|tls handshake|connection reset|connection refused|EOF|unexpected EOF|read: connection|net/http: TLS handshake|context deadline exceeded|Client\.Timeout exceeded|timeout awaiting response headers|timeout awaiting response body|request canceled' # Discovery flag: callers that need to share the same regex (for example the # inline retag-inspect retry loop, which must drop a couple of patterns the