Skip to content

fix(agent): prevent panic in parseImageDetails for digest-pinned images#1723

Merged
suyadav1 merged 1 commit into
ci_prodfrom
suyadav/fix-image-parsing
Jun 29, 2026
Merged

fix(agent): prevent panic in parseImageDetails for digest-pinned images#1723
suyadav1 merged 1 commit into
ci_prodfrom
suyadav/fix-image-parsing

Conversation

@suyadav1

Copy link
Copy Markdown
Contributor

Summary

parseImageDetails could panic with slice bounds out of range when processing digest-pinned, tagless container images (e.g. quay.io/openshift-release-dev/ocp-release@sha256:...), which are ubiquitous on OpenShift. The panic crashed fluent-bit's out_oms plugin during flush and crash-looped the ama-logs daemonset on affected clusters (observed restartCount in the hundreds, with intermittent/zero ContainerLogV2 ingestion).

Root cause

colonLocation (the tag delimiter) was computed on the full image string, before the @<digest> suffix was stripped:

slashLocation := strings.Index(image, "/")
colonLocation := strings.Index(image, ":")   // finds ':' inside "sha256:"
atLocation := strings.Index(image, "@")
if atLocation != -1 { image = image[:atLocation] }   // image is now shorter
...
name = image[slashLocation+1 : colonLocation]        // colonLocation > len(image) -> panic

For quay.io/openshift-release-dev/ocp-release@sha256:ed3b...:

  • colonLocation = 48 (the : in sha256:)
  • after @ truncation, len(image) = 41
  • name = image[8:48]slice bounds out of range [:48] with length 41

The existing if colonLocation < len(image) guard only protected the tag slice; the panic happened one block earlier on the unguarded name slice. This path is reached through KubernetesMetadata enrichment: FLBPluginFlushPostDataHelperprocessIncludesparseImageDetails.

Fix

Move the @<digest> truncation to the top of the function so slashLocation and colonLocation are computed on the already-cleaned string and can never exceed its length. Behavior is unchanged for all previously-working formats.

Tests

  • TestParseImageDetails — table-driven, 15 cases covering every reference form: bare name, name:tag, name@digest, namespace/name (+tag/+digest), host/path (+tag/+digest), multi-segment paths, tag and digest, the OpenShift digest-tagless case (the panic repro), registry:port quirks, and empty string.
  • TestProcessIncludesDigestPinnedImage — exercises the end-to-end metadata path that previously panicked.

go build ./... and go test ./source/plugins/go/src both pass.

Notes

The simplified parser still mis-splits a registry with an explicit :port (e.g. myregistry.io:5000/team/app:1.0) — this is pre-existing, non-panicking behavior and is documented as a known limitation in the new tests.

parseImageDetails computed the colon (tag) position on the full image
string *before* stripping the @digest suffix. For digest-pinned, tagless
images such as quay.io/openshift-release-dev/ocp-release@sha256:... —
ubiquitous on OpenShift — the colon inside "sha256:" produced a
colonLocation past the truncated string length, causing a
"slice bounds out of range" panic at `name = image[slashLocation+1 : colonLocation]`.

This panic occurred in the out_oms flush path via the KubernetesMetadata
enrichment (processIncludes -> parseImageDetails), core-dumping fluent-bit
and crash-looping the ama-logs daemonset on affected clusters.

Fix: move the @digest truncation to the top of the function so the slash
and colon positions are computed on the already-cleaned string and can
never exceed its length.

Add a table-driven TestParseImageDetails covering all image reference
formats (bare name, name+tag, name+digest, namespace/name, host/path,
multi-segment paths, tag+digest, registry:port quirks, and empty string)
plus TestProcessIncludesDigestPinnedImage exercising the end-to-end
metadata path that previously panicked.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@suyadav1 suyadav1 requested a review from a team as a code owner June 29, 2026 18:34
Comment thread source/plugins/go/src/oms_test.go Dismissed
Comment thread source/plugins/go/src/oms_test.go Dismissed
Comment thread source/plugins/go/src/oms_test.go Dismissed
@suyadav1

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@suyadav1 suyadav1 merged commit d836602 into ci_prod Jun 29, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants