dagger/dagger · error

invalid image config for export: missing architecture

Error message

invalid image config for export: missing architecture

What it means

patchImageConfig likewise requires a non-empty 'architecture' field; otherwise it returns "invalid image config for export: missing architecture". The OCI spec mandates architecture in the image config for the manifest to be usable.

Source

Thrown at engine/engineutil/imageexport/writer.go:466

func patchImageConfig(dt []byte, descs []ocispecs.Descriptor, history []ocispecs.History, inlineCache []byte, epoch *time.Time, baseImg *dockerspec.DockerOCIImage) ([]byte, error) {
	var img ocispecs.Image
	if err := json.Unmarshal(dt, &img); err != nil {
		return nil, errors.Wrap(err, "invalid image config for export")
	}

	m := map[string]json.RawMessage{}
	if err := json.Unmarshal(dt, &m); err != nil {
		return nil, errors.Wrap(err, "failed to parse image config for patch")
	}
	if m == nil {
		return nil, errors.Errorf("invalid null image config for export")
	}
	if img.OS == "" {
		return nil, errors.Errorf("invalid image config for export: missing os")
	}
	if img.Architecture == "" {
		return nil, errors.Errorf("invalid image config for export: missing architecture")
	}

	rootFS := ocispecs.RootFS{Type: "layers"}
	for _, desc := range descs {
		rootFS.DiffIDs = append(rootFS.DiffIDs, digest.Digest(desc.Annotations[labels.LabelUncompressed]))
	}
	rootJSON, err := json.Marshal(rootFS)
	if err != nil {
		return nil, errors.Wrap(err, "failed to marshal rootfs")
	}
	m["rootfs"] = rootJSON

	if epoch != nil {
		var divergedFromBase bool
		for i, h := range history {
			if !divergedFromBase && baseImg != nil && i < len(baseImg.History) && reflect.DeepEqual(h, baseImg.History[i]) {
				continue
			}

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Add "architecture": "amd64" (or arm64 etc.) to the image config
  2. Populate Platform.Architecture from platforms.DefaultSpec()/Normalize when building configs in code
  3. Rebuild the base image with a conformant toolchain

Example fix

// before
{"os": "linux", "rootfs": {"type": "layers", "diff_ids": []}}
// after
{"os": "linux", "architecture": "amd64", "rootfs": {"type": "layers", "diff_ids": []}}
Defensive patterns

Strategy: validation

Validate before calling

func hasArchitecture(dt []byte) bool {
  var img ocispecs.Image
  if json.Unmarshal(dt, &img) != nil { return false }
  return img.Architecture != ""
}

Type guard

func configHasArch(img ocispecs.Image) bool { return img.Architecture != "" }

Try / catch

if err != nil && strings.Contains(err.Error(), "missing architecture") {
  // inject defaults: img.Architecture = platforms.Normalize(platforms.DefaultSpec()).Architecture and retry
}

Prevention

When it happens

Trigger: commitPlatformManifest -> patchImageConfig with a config JSON missing 'architecture' or containing an empty string — same root causes as the missing-os case: hand-rolled or minimal configs.

Common situations: Scripts generating image configs that set os but forget architecture; programmatic exports supplying partial Image structs; base images from non-conformant build tools.

Related errors


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