slimtoolkit/slim · error
no layers
Error message
no layers
What it means
Engine.Build assembles an image from the provided layer blobs/tarballs. With an empty Layers slice the resulting image would have no filesystem content, so Build fails fast with 'no layers' to avoid producing a broken or empty image.
Source
Thrown at pkg/imagebuilder/internalbuilder/engine.go:58
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")
}
var img v1.Image
if options.From == "" {
//same as FROM scratch
img = empty.ImageView on GitHub (pinned to 81940d17fa)
Solutions
- Populate options.Layers with at least one layer archive before calling Build; verify layer creation returned non-empty output.
- Debug the upstream layer-generation code: check include/exclude globs and source paths so files are actually captured.
- If a truly empty image is intended, use a builder path that allows it or add a minimal layer containing the runtime files.
Example fix
// before
opts := imagebuilder.SimpleBuildOptions{ImageConfig: cfg} // Layers empty
res, err := engine.Build(opts) // no layers
// after
layer, err := archive.TarWithOptions(appDir, &archive.TarOptions{})
if err != nil { return err }
opts := imagebuilder.SimpleBuildOptions{ImageConfig: cfg, Layers: []string{layerPath}}
res, err := engine.Build(opts) Defensive patterns
Strategy: validation
Validate before calling
func hasLayers(opts imagebuilder.SimpleBuildOptions) bool {
return len(opts.Layers) > 0
}
if !hasLayers(opts) {
return errors.New("refusing to build: no layers were produced upstream")
}
res, err := engine.Build(opts) Try / catch
res, err := engine.Build(opts)
if err != nil {
switch {
case strings.Contains(err.Error(), "no layers"):
return nil, fmt.Errorf("layer generation produced nothing; check source dirs and include globs: %w", err)
case strings.Contains(err.Error(), "missing startup info"):
return nil, fmt.Errorf("image config lacks CMD/ENTRYPOINT: %w", err)
}
return nil, err
} Prevention
- Verify layer archiving output is non-empty before Build
- Log layer counts at generation time to catch empty results early
- Audit include/exclude patterns that can silently filter everything
- Add a pre-build validator covering layers plus startup info
When it happens
Trigger: Calling engine.Build with SimpleBuildOptions.Layers of length 0 — e.g. layer archiving upstream produced nothing (empty source dir, all files filtered), or options were constructed without appending any layer entries.
Common situations: A COPY/collect step silently produced an empty directory that was then skipped; layer generation code filtered out every file (bad include patterns); config assembled programmatically with Layers forgotten while startup info was set.
Related errors
- missing startup info
- bad parameter
- dockerimage.LoadPackage: missing layer (%v) for image ID - %
- dockerimage.LoadPackage: layer index mismatch - %v / %v
- dockerimage.LoadPackage: layer path mismatch - %v / %v
AI-assisted analysis of slimtoolkit/slim@81940d17fa (2026-08-31).
Data as JSON: /api/errors/a8d19f5e905df0b5.
Report an issue: GitHub.