dagger/dagger · error
failed to encode spec: %w
Error message
failed to encode spec: %w
What it means
The engine failed to write the container's OCI runtime spec as the runc bundle config.json (json.NewEncoder(f).Encode(state.spec)). runc cannot start a container without a valid bundle config, so this aborts the container run.
Source
Thrown at engine/engineutil/executor_spec.go:1250
func (c *Client) runContainer(ctx context.Context, state *execState) (rerr error) {
bundle := filepath.Join(c.ExecutorRoot, state.id)
if err := os.Mkdir(bundle, 0o711); err != nil {
return err
}
state.cleanups.Add("remove bundle", func() error {
return os.RemoveAll(bundle)
})
configPath := filepath.Join(bundle, "config.json")
f, err := os.Create(configPath)
if err != nil {
return err
}
defer f.Close()
if err := json.NewEncoder(f).Encode(state.spec); err != nil {
return fmt.Errorf("failed to encode spec: %w", err)
}
f.Close()
lg := bklog.G(ctx).
WithField("id", state.id).
WithField("args", state.spec.Process.Args)
if state.execMD != nil {
if state.execMD.CallDigest != "" {
lg = lg.WithField("call_id", state.execMD.CallDigest)
}
}
if state.callerClientID != "" {
lg = lg.WithField("caller_client_id", state.callerClientID)
}
if state.nestedClientMetadata != nil && state.nestedClientMetadata.ClientID != "" {
lg = lg.WithField("nested_client_id", state.nestedClientMetadata.ClientID)
}
lg.Info("starting container")
defer func() {View on GitHub (pinned to 82ba2681db)
Solutions
- Check engine host disk space (df) — ENOSPC on the executor root is the most common cause
- Check the wrapped inner error to distinguish write failure from marshal failure
- Free space or move the engine's data root; restart the engine to clear stale bundles
- If it's a marshal error, check for non-serializable spec fields (custom builds)
Example fix
// diagnosis // before (engine host) df -h /var/lib/dagger // after: free space or remount storage, then rerun the pipeline
Defensive patterns
Strategy: validation
Validate before calling
// Precheck on the engine host before starting work:
// stat -f -c '%a %T' <executor-root> (free blocks/inodes)
// alert if free space below threshold, e.g.:
if free, err := diskFree(executorRoot); err == nil && free < 1<<30 {
return fmt.Errorf("insufficient disk (%d bytes free) for runc bundle", free)
} Try / catch
// Go
if err := json.NewEncoder(f).Encode(state.spec); err != nil {
var jerr *json.UnsupportedTypeError
if !errors.As(err, &jerr) { // then it was a write error
bklog.G(ctx).Errorf("config.json write failed (disk full?): %v", err)
}
return fmt.Errorf("failed to encode spec: %w", err)
} Prevention
- Monitor disk space and inodes on the engine data root
- Set up log rotation / prune old engine state
- Alert on ENOSPC in engine logs
- Restart the engine after disk-full incidents to clear stale bundles
When it happens
Trigger: Encoding specs.Spec to the already-created config.json file errors. Since a plain *os.File encode only fails on write errors, this is typically ENOSPC/disk-full, I/O error, or a spec value that fails to marshal (rare).
Common situations: Engine host disk full (bundle dir on a full filesystem); storage backend errors; I/O failures on the engine's executor root mount.
Related errors
- marshal introspection schema for self-call merge: %w
- unmarshal merged introspection JSON: %w
- marshal introspection response: %w
- decode persisted changeset payload: %w
- decode persisted container withoutEntrypoint lazy payload: %
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/1fea3484de6b9bd5.
Report an issue: GitHub.