{"record":{"id":"dca6eebfed7ed3e6","repo":"jdx/mise","slug":"blob-chunk-upload-failed","errorCode":null,"errorMessage":"blob chunk upload failed: {}{}\n{}","messagePattern":"blob chunk upload failed: (.+?)(.+?)\n(.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/oci/registry.rs","lineNumber":1405,"sourceCode":"                            offset,\n                            len,\n                            pr,\n                            &err_slot,\n                        )\n                        // Content-Range is inclusive on both ends.\n                        .header(\"Content-Range\", format!(\"{}-{}\", offset, offset + len - 1)))\n                    })\n                    .await\n                    .wrap_err(\"PATCH blob chunk\")?;\n                check_upload_err(&err_slot, path)?;\n                let status = resp.status();\n                // Per the OCI dist-spec a chunk PATCH returns 202 Accepted, but\n                // AWS ECR answers with 201 Created. Accept both, as the\n                // finalizing PUT below already does.\n                if status != StatusCode::ACCEPTED && status != StatusCode::CREATED {\n                    resp.error_for_status_ref()?;\n                    let body = resp.text().await.unwrap_or_default();\n                    bail!(\n                        \"blob chunk upload failed: {}{}\\n{}\",\n                        status.as_u16(),\n                        push_auth_hint(status, had_credential),\n                        body.trim(),\n                    );\n                }\n                location = self.resolve_location(&resp).unwrap_or(location);\n                offset += len;\n            }\n            // Finalize with ?digest=…\n            let mut put_url = location;\n            put_url.query_pairs_mut().append_pair(\"digest\", digest);\n            let resp = self\n                .session\n                .send(|auth| {\n                    let mut rb = HTTP\n                        .reqwest()?\n                        .put(put_url.as_str())","sourceCodeStart":1387,"sourceCodeEnd":1423,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/oci/registry.rs#L1387-L1423","documentation":"Thrown when a chunked PATCH upload of blob data returns a status other than 202 Accepted (or 201 Created, which AWS ECR returns despite the spec). The error carries the status, an auth hint, and the registry's response body.","triggerScenarios":"`upload_blob_once` PATCHing a chunk to the registry's upload session URL and receiving e.g. 416 (wrong chunk range), 401 (session token expired), or 5xx from a flaky registry.","commonSituations":"Very large layers where mid-upload auth tokens expire; uploading to registries that deviate from the dist-spec beyond the ECR 201 case; network middleboxes corrupting chunk ranges (416); self-hosted registry misconfiguration.","solutions":["Re-authenticate (`docker login`) — expired bearer tokens commonly cause mid-upload 401s.","Retry the push; upload sessions are restarted and the chunk offsets recomputed.","For 416, verify no proxy is modifying/duplicating requests and Content-Range headers.","Try a monolithic (single PUT) upload path if the registry's PATCH support is broken."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match upload_blob(blob) {\n    Err(e) if e.to_string().contains(\"401\") => { relogin(); retry(1); }\n    Err(e) if is_transient(&e) => backoff_retry(3),\n    other => other,\n}","preventionTips":["For large layers, obtain a fresh token right before upload to avoid mid-upload expiry.","Avoid proxies that rewrite/normalize chunked requests (cause 416).","Test the registry's PATCH support if not using ECR (which needs the 201 exception the code already handles)."],"tags":["network","http","oci","push","blob-upload"],"backgroundTag":"http-error-response","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}