slimtoolkit/slim · error

missing startup info

Error message

missing startup info

What it means

The internal builder's Engine.Build produces an image whose process can actually start. If the provided image config defines neither an ENTRYPOINT nor a CMD, there is no startup command and Build refuses with 'missing startup info'. The library will not invent a default command for the image.

Source

Thrown at pkg/imagebuilder/internalbuilder/engine.go:54

// New creates new Engine instances
func New(
	showBuildLogs bool,
	pushToDaemon bool,
	pushToRegistry bool) (*Engine, error) {

	engine := &Engine{
		ShowBuildLogs:  showBuildLogs,
		PushToDaemon:   pushToDaemon,
		PushToRegistry: pushToRegistry,
	}

	return engine, nil
}

func (ref *Engine) Build(options imagebuilder.SimpleBuildOptions) (*imagebuilder.ImageResult, error) {
	if len(options.ImageConfig.Config.Entrypoint) == 0 &&
		len(options.ImageConfig.Config.Cmd) == 0 {
		return nil, fmt.Errorf("missing startup info")
	}

	if len(options.Layers) == 0 {
		return nil, fmt.Errorf("no layers")
	}

	if len(options.Layers) > 255 {
		return nil, fmt.Errorf("too many layers")
	}

	switch options.ImageConfig.Architecture {
	case "":
		options.ImageConfig.Architecture = "amd64"
	case "arm64", "amd64":
	default:
		return nil, fmt.Errorf("bad architecture value")
	}

View on GitHub (pinned to 81940d17fa)

Solutions

  1. Set Config.Cmd in SimpleBuildOptions.ImageConfig to the desired default command, e.g. ["/app/server"].
  2. Set Config.Entrypoint instead if the image should behave as an executable wrapper.
  3. If the image is intentionally non-runnable (a data/base image), use a different builder path or add a trivial CMD like ["true"].

Example fix

// before
opts := imagebuilder.SimpleBuildOptions{Layers: layers}
res, err := engine.Build(opts) // missing startup info
// after
opts := imagebuilder.SimpleBuildOptions{Layers: layers}
opts.ImageConfig.Config.Cmd = []string{"/app/run"}
res, err := engine.Build(opts)
Defensive patterns

Strategy: validation

Validate before calling

func hasStartupInfo(cfg imagebuilder.SimpleBuildOptions) bool {
	c := cfg.ImageConfig.Config
	return len(c.Entrypoint) > 0 || len(c.Cmd) > 0
}

if !hasStartupInfo(opts) {
	opts.ImageConfig.Config.Cmd = []string{"/app/run"}
}
res, err := engine.Build(opts)

Type guard

func isRunnable(config imagebuilder.Config) bool {
	return len(config.Entrypoint) > 0 || len(config.Cmd) > 0
}

Try / catch

res, err := engine.Build(opts)
if err != nil {
	if strings.Contains(err.Error(), "missing startup info") {
		opts.ImageConfig.Config.Cmd = []string{"/bin/true"}
		return engine.Build(opts)
	}
	return nil, err
}

Prevention

When it happens

Trigger: Calling engine.Build with imagebuilder.SimpleBuildOptions whose ImageConfig.Config.Entrypoint and Cmd are both empty arrays — e.g. building from a Dockerfile that only has FROM/ENV lines, or constructing the config manually without setting either field.

Common situations: Parsing a base-image-only Dockerfile through SimpleBuildOptionsFromDockerfileData; hand-assembled image configs for batch/init images where the author forgot CMD; Dockerfiles relying on a parent image's ENTRYPOINT without restating it.

Related errors


AI-assisted analysis of slimtoolkit/slim@81940d17fa (2026-08-31). Data as JSON: /api/errors/703be55ed2a9f401. Report an issue: GitHub.