{"record":{"id":"714962aec6f2a884","repo":"elastic/elasticsearch","slug":"no-manifest-digest-found-in-oci-image-layout-index","errorCode":null,"errorMessage":"No manifest digest found in OCI image layout index [{indexJson}]","messagePattern":"No manifest digest found in OCI image layout index \\[(.+?)\\]","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/docker/DockerBuildTask.java","lineNumber":345,"sourceCode":"        /**\n         * Resolves an {@code oci-layout://} build context value to a digest-qualified reference.\n         * Buildx resolves OCI layout contexts by tag or digest within the layout; the tag recorded\n         * in the layout's index is not always what buildx looks up by default, so pinning the\n         * manifest digest from {@code index.json} is the most robust way to reference the\n         * (single-image) layouts we export.\n         */\n        private static String resolveBuildContext(String value) {\n            String prefix = \"oci-layout://\";\n            if (value.startsWith(prefix) == false || value.contains(\"@\")) {\n                return value;\n            }\n            Path indexJson = Path.of(value.substring(prefix.length()), \"index.json\");\n            try {\n                // The exported layouts contain a single manifest, so plucking the first digest is\n                // sufficient and avoids a JSON parser dependency in this worker action.\n                Matcher matcher = Pattern.compile(\"sha256:[a-f0-9]{64}\").matcher(Files.readString(indexJson));\n                if (matcher.find() == false) {\n                    throw new GradleException(\"No manifest digest found in OCI image layout index [\" + indexJson + \"]\");\n                }\n                return value + \"@\" + matcher.group();\n            } catch (IOException e) {\n                throw new UncheckedIOException(\"Failed to read OCI image layout index [\" + indexJson + \"]\", e);\n            }\n        }\n\n        private boolean isCrossPlatform() {\n            return getParameters().getPlatforms()\n                .get()\n                .stream()\n                .anyMatch(any -> any.equals(Architecture.current().dockerPlatform) == false);\n        }\n\n        private String getImageChecksum(String imageTag) {\n            final ByteArrayOutputStream stdout = new ByteArrayOutputStream();\n            String docker = getParameters().getDockerExecutable().get();\n","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/docker/DockerBuildTask.java#L327-L363","documentation":"Thrown by DockerBuildTask.resolveBuildContext() when an `oci-layout://` build-context value has no `@digest` suffix and the referenced layout's `index.json` does not contain a SHA-256 manifest digest matching `sha256:[a-f0-9]{64}`. The method resolves OCI-layout contexts by pinning the manifest digest so buildx references the image unambiguously; if no digest is found, the layout is malformed or empty and the build cannot proceed. This is a GradleException naming the index.json path.","triggerScenarios":"A Docker build is configured to use an `oci-layout://<path>` build context (typically pointing at an exported local layout). The path's `index.json` either does not exist as expected, is empty, or contains no `sha256:<64-hex>` digest. This happens when the layout export that was supposed to produce the context failed silently, produced an empty index, or wrote a digest in a format the regex does not recognize (e.g. uppercase hex).","commonSituations":"A prior task that exports the OCI layout failed or was skipped, leaving a partial/empty index.json; the layout was hand-constructed incorrectly; the digest uses uppercase A-F which the lowercase-only regex `[a-f0-9]` rejects; the path prefix `oci-layout://` was typo'd so the wrong directory is read.","solutions":["Inspect the reported index.json: confirm it exists and contains a `\"digest\": \"sha256:<64 lowercase hex>\"` entry.","Re-run whatever task exports/produces the OCI layout so index.json is regenerated correctly.","If the digest is uppercase, regenerate the layout with a tool that emits lowercase, or fix the producer.","Verify the `oci-layout://` path points at the correct layout directory (typo in build config)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before building, for each oci-layout:// context assert index.json contains a lowercase sha256 digest:\n// String json = Files.readString(indexJson);\n// if (!Pattern.compile(\"sha256:[a-f0-9]{64}\").matcher(json).find()) fail(\"no digest in \" + indexJson);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure the OCI-layout-producing task runs before the Docker build task (declare a proper task dependency).","Verify exported layouts contain a lowercase sha256 digest in index.json.","Double-check the `oci-layout://` path spelling in build config."],"tags":["docker","build","oci","validation"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}