dagger/dagger · error

cannot get layer information from mount option (type = %q)

Error message

cannot get layer information from mount option (type = %q)

What it means

In the one-lower/one-upper case, GetUpperdir parses lowerdir information out of the lower mount's options via GetOverlayLayers. If the lower mount is neither a bind mount nor an overlay mount type, the engine cannot extract layer info and returns this error naming the offending type. It means the lower snapshot's mounts are not in a form the overlay differ understands.

Source

Thrown at engine/snapshots/fsdiff/overlay_linux.go:44

	if len(lower) == 0 && len(upper) == 1 {
		upperM := upper[0]
		if upperM.Type != "bind" {
			return "", errors.Errorf("bottommost upper must be bind mount but %q", upperM.Type)
		}
		upperdir = upperM.Source
	} else if len(lower) == 1 && len(upper) == 1 {
		var lowerlayers []string
		lowerM := lower[0]
		if lowerM.Type == "bind" {
			lowerlayers = []string{lowerM.Source}
		} else if IsOverlayMountType(lowerM) {
			var err error
			lowerlayers, err = GetOverlayLayers(lowerM)
			if err != nil {
				return "", err
			}
		} else {
			return "", errors.Errorf("cannot get layer information from mount option (type = %q)", lowerM.Type)
		}

		upperM := upper[0]
		if !IsOverlayMountType(upperM) {
			return "", errors.Errorf("upper snapshot isn't overlay mounted (type = %q)", upperM.Type)
		}
		upperlayers, err := GetOverlayLayers(upperM)
		if err != nil {
			return "", err
		}

		if len(upperlayers) != len(lowerlayers)+1 {
			return "", errors.Errorf("cannot determine diff of more than one upper directories")
		}
		for i := 0; i < len(lowerlayers); i++ {
			if upperlayers[i] != lowerlayers[i] {
				return "", errors.Errorf("layer %d must be common between upper and lower snapshots", i)
			}

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Verify both snapshots belong to the overlay-based snapshotter; re-create snapshots with the overlay snapshotter if they came from native/btrfs/zfs.
  2. Extend or check GetOverlayLayers support for the mount type you actually have, or route non-overlay snapshots to a different differ.
  3. Dump lower[0] (Type + Options) and confirm it is a standard overlay mount with lowerdir= options.
  4. Align engine/snapshotter versions so mount-type naming matches what GetUpperdir recognizes.

Example fix

// before: assumes overlay-compatible lower
mtrs, err := sn.Mounts(ctx, chainID)
upper, err := fsdiff.GetUpperdir(mtrs[:1], mtrs[1:])
// after
if !fsdiff.IsOverlayMountType(mtrs[0]) && mtrs[0].Type != "bind" {
    return fmt.Errorf("fsdiff requires overlay or bind lower mount, got %q", mtrs[0].Type)
}
upper, err = fsdiff.GetUpperdir(mtrs[:1], mtrs[1:])
Defensive patterns

Strategy: validation

Validate before calling

lowerM := lower[0]
if lowerM.Type != "bind" && !fsdiff.IsOverlayMountType(lowerM) {
    return fmt.Errorf("fsdiff needs bind/overlay lower mount, got %q", lowerM.Type)
}

Type guard

func lowerSupported(m mount.Mount) bool {
    return m.Type == "bind" || fsdiff.IsOverlayMountType(m)
}

Try / catch

upper, err := fsdiff.GetUpperdir(lower, upperM)
if err != nil && strings.Contains(err.Error(), "cannot get layer information from mount option") {
    return fmt.Errorf("lower snapshot from incompatible snapshotter (type %s); recreate with overlay snapshotter", lower[0].Type)
}

Prevention

When it happens

Trigger: differFor -> GetUpperdir with len(lower)==1 and lower[0].Type not in ("bind", overlay types recognized by IsOverlayMountType/GetOverlayLayers) — e.g. native, copy-on-write2, fuse-overlayfs, or a custom snapshotter's mount type.

Common situations: Differencing snapshots taken by a non-overlay snapshotter (native, btrfs, zfs) while the fsdiff overlay differ expects overlay/bind semantics; plugin snapshotters emitting novel mount types; stale snapshots created before a snapshotter switch.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/5b67de20c838404c. Report an issue: GitHub.