{"record":{"id":"68d826414cb6ad40","repo":"jdx/mise","slug":"manifest-push-failed-url","errorCode":null,"errorMessage":"manifest push failed: {} {url}{}\n{}","messagePattern":"manifest push failed: (.+?) (.+?)(.+?)\n(.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/oci/registry.rs","lineNumber":1516,"sourceCode":"        let resp = self\n            .session\n            .send(|auth| {\n                let mut rb = HTTP\n                    .reqwest()?\n                    .put(&url)\n                    .header(\"Content-Type\", media_type)\n                    .body(body.clone());\n                if let Some(a) = auth {\n                    rb = rb.header(\"Authorization\", a);\n                }\n                Ok(rb)\n            })\n            .await\n            .wrap_err_with(|| format!(\"PUT {url}\"))?;\n        let status = resp.status();\n        if !status.is_success() {\n            let body = resp.text().await.unwrap_or_default();\n            bail!(\n                \"manifest push failed: {} {url}{}\\n{}\",\n                status.as_u16(),\n                push_auth_hint(status, had_credential),\n                body.trim(),\n            );\n        }\n        Ok(())\n    }\n\n    /// Point `tag` at an OCI image index containing `entry` plus whatever\n    /// other-platform entries the tag already carries. Returns the digest of\n    /// the pushed index.\n    ///\n    /// NOTE: read-modify-write without registry-side concurrency control (the\n    /// Distribution spec has no conditional manifest PUT), so two runners\n    /// updating the same tag at the same instant can race — sequence\n    /// per-platform pushes in CI when that matters.\n    async fn update_tag_index(&mut self, tag: &str, entry: Descriptor) -> Result<String> {","sourceCodeStart":1498,"sourceCodeEnd":1534,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/oci/registry.rs#L1498-L1534","documentation":"put_manifest fails when the OCI registry responds with a non-success HTTP status to a manifest PUT. The message embeds the status code, an authentication hint computed from whether credentials were supplied, the URL, and the trimmed registry response body so the developer can see the registry's own reason.","triggerScenarios":"push_image or update_tag_index PUTs an image manifest/index to a registry and the registry returns 4xx/5xx — e.g. 401/403 from missing or expired credentials, 404 because the repository was never created, 422/400 from a malformed manifest, or a blob referenced by the manifest was never pushed.","commonSituations":"Unauthenticated push (no credential for the registry host), wrong registry URL in config, pushing to a namespace the account cannot write, tag name or manifest schema rejected by the registry, expired token.","solutions":["Read the registry body in the error for the exact registry-side reason","Run the push again with credentials configured (e.g. docker login equivalent / mise credential settings) so the auth hint goes away","Verify the repository exists and the account has push permission to that namespace","Check that all layers/blobs referenced by the manifest were pushed before the manifest","Confirm the manifest format/tag string is accepted by the registry"],"exampleFix":"// before\n// registry.push_image(...) fails with 401: manifest push failed: 401 https://ghcr.io/v2/org/img/manifests/v1 UNAUTHORIZED\n// after\n// configure credentials for ghcr.io first (e.g. mise config: [packslip.auth.\"ghcr.io\"] username/token), then retry the push","handlingStrategy":"try-catch","validationCode":"// verify credentials exist before pushing\nif (!creds.has(\"ghcr.io\")) throw new Error(\"configure registry credentials before push\");","typeGuard":null,"tryCatchPattern":"try { await registry.putManifest(...) } catch (e) { if (/manifest push failed: (401|403)/.test(e.message)) { fixCredentials(); } else { throw e; } }","preventionTips":["Configure registry credentials before pushing","Push all blobs/layers before the manifest","Keep tag names within registry constraints","Check repository write permissions for your account"],"tags":["oci","registry","http","push","authentication"],"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"}