{"record":{"id":"722d6ebfb019982f","repo":"containerd/containerd","slug":"index-out-of-bounds-d-has-d-active-mounts","errorCode":null,"errorMessage":"index out of bounds: %d, has %d active mounts","messagePattern":"index out of bounds: (.+?), has (.+?) active mounts","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/mount/manager/format.go","lineNumber":80,"sourceCode":"\t\t}\n\t}\n\tif o != nil {\n\t\tm.Options = o\n\t}\n\treturn m, nil\n}\n\nfunc formatString(s string) func([]mount.ActiveMount) (string, error) {\n\tif !strings.Contains(s, formatCheck) {\n\t\treturn nil\n\t}\n\n\treturn func(a []mount.ActiveMount) (string, error) {\n\t\t// TODO: The formatting is very easy, don't use template\n\t\tfm := template.FuncMap{\n\t\t\t\"source\": func(i int) (string, error) {\n\t\t\t\tif i < 0 || i >= len(a) {\n\t\t\t\t\treturn \"\", fmt.Errorf(\"index out of bounds: %d, has %d active mounts\", i, len(a))\n\t\t\t\t}\n\t\t\t\treturn a[i].Source, nil\n\t\t\t},\n\t\t\t\"target\": func(i int) (string, error) {\n\t\t\t\tif i < 0 || i >= len(a) {\n\t\t\t\t\treturn \"\", fmt.Errorf(\"index out of bounds: %d, has %d active mounts\", i, len(a))\n\t\t\t\t}\n\t\t\t\treturn a[i].Target, nil\n\t\t\t},\n\t\t\t\"mount\": func(i int) (string, error) {\n\t\t\t\tif i < 0 || i >= len(a) {\n\t\t\t\t\treturn \"\", fmt.Errorf(\"index out of bounds: %d, has %d active mounts\", i, len(a))\n\t\t\t\t}\n\t\t\t\treturn a[i].MountPoint, nil\n\t\t\t},\n\t\t\t\"overlay\": func(start, end int) (string, error) {\n\t\t\t\tvar dirs []string\n\t\t\t\tif start > end {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/core/mount/manager/format.go#L62-L98","documentation":"The mount manager expands Go-template placeholders in mount Source/Target/Options (e.g. {{ source 0 }}, {{ mount 1 }}) against the list of ActiveMounts. The 'source' template function returns this error when the template's index is negative or >= the number of active mounts, guarding against a slice panic.","triggerScenarios":"A mount spec whose Source contains a template like {{ source 5 }} but Transform/Mount is invoked with fewer than 6 ActiveMount entries (or a negative index, e.g. computed from a bad snapshot ID).","commonSituations":"Overlay/snapshotter configurations where the template index assumes more parent layers than actually exist (pruned or flattened snapshots); mounts applied to the wrong snapshotter with a different layer count; off-by-one in generated mount options.","solutions":["Reduce the template index in the mount Source (e.g. {{ source 0 }}) to be within the actual number of active mounts.","Log len(activeMounts) at the call site and compare against the index used in the template to find the mismatch.","Fix the snapshotter/packager that emitted the mount spec so its template matches the layer count it produces.","Validate mount templates at snapshot-preparation time rather than failing at mount time."],"exampleFix":"// before\nOptions: []string{\"upperdir={{ mount 3 }}/fs\", \"workdir={{ mount 3 }}/work\"}\n// after (only 2 active mounts exist)\nOptions: []string{\"upperdir={{ mount 1 }}/fs\", \"workdir={{ mount 1 }}/work\"}","handlingStrategy":"validation","validationCode":"// before mounting, ensure template indices fit the active mount count\nfor _, opt := range mount.Options {\n    for _, m := range indexRegexp.FindAllStringSubmatch(opt, -1) {\n        i, _ := strconv.Atoi(m[1])\n        if i < 0 || i >= len(activeMounts) {\n            return fmt.Errorf(\"template index %d out of range for %d mounts\", i, len(activeMounts))\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"_, err := mgr.Mount(ctx, mounts...)\nif err != nil {\n    var ierr *fmt.Errorf\n    if strings.Contains(err.Error(), \"index out of bounds\") {\n        return fmt.Errorf(\"mount template references missing snapshot layer: %w\", err)\n    }\n    return err\n}","preventionTips":["Compute template indices from the snapshot's actual layer list instead of hardcoding.","Regenerate mount specs after snapshot GC or layer pruning.","Validate mount templates against len(activeMounts) at preparation time."],"tags":["template","mount","index-out-of-range","snapshotter"],"backgroundTag":"mount-template-index-out-of-bounds","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}