dagger/dagger · error

parse DAGGER_ENGINE_NUM_CPU: %w

Error message

parse DAGGER_ENGINE_NUM_CPU: %w

What it means

Inside a nested Dagger session, the optional DAGGER_ENGINE_NUM_CPU env var is read to configure engine CPU count. If present but not a valid integer, Connect fails with this wrapped strconv error. It only triggers when the variable is non-empty, so the variable exists but holds non-numeric content.

Source

Thrown at engine/client/client.go:277

	// NB: don't propagate this ctx, we don't want everything tucked beneath connect
	connectCtx, span := Tracer(ctx).Start(ctx, "connect", connectSpanOpts...)
	defer telemetry.EndWithCause(span, &rerr)
	slog := slog.SpanLogger(connectCtx, InstrumentationLibrary)

	nestedSessionPortVal, isNestedSession := os.LookupEnv("DAGGER_SESSION_PORT")
	if isNestedSession {
		nestedSessionPort, err := strconv.Atoi(nestedSessionPortVal)
		if err != nil {
			return nil, fmt.Errorf("parse DAGGER_SESSION_PORT: %w", err)
		}
		c.nestedSessionPort = nestedSessionPort
		c.SecretToken = os.Getenv("DAGGER_SESSION_TOKEN")
		numCPUVal := os.Getenv("DAGGER_ENGINE_NUM_CPU")
		if numCPUVal != "" {
			numCPU, err := strconv.Atoi(numCPUVal)
			if err != nil {
				return nil, fmt.Errorf("parse DAGGER_ENGINE_NUM_CPU: %w", err)
			}
			c.numCPU = numCPU
		}
		c.httpClient = c.newHTTPClient()
		if err := c.init(connectCtx); err != nil {
			return nil, fmt.Errorf("initialize nested client: %w", err)
		}
		if err := c.subscribeTelemetry(connectCtx); err != nil {
			return nil, fmt.Errorf("subscribe to telemetry: %w", err)
		}
		if err := c.daggerConnect(connectCtx); err != nil {
			return nil, fmt.Errorf("failed to connect to dagger: %w", err)
		}
		return c, nil
	}

	// Check if any of the upstream cache importers/exporters are enabled.
	// Note that this is not the cache service support in engine/cache/, that

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Unset DAGGER_ENGINE_NUM_CPU if you don't need to override CPU count: unset DAGGER_ENGINE_NUM_CPU.
  2. Set it to a plain positive integer: export DAGGER_ENGINE_NUM_CPU=4.
  3. Convert float/unit values to integers at the source (e.g. in the engine launcher that exports the variable).

Example fix

// before
export DAGGER_ENGINE_NUM_CPU=4.0
// after
export DAGGER_ENGINE_NUM_CPU=4
Defensive patterns

Strategy: validation

Validate before calling

if v := os.Getenv("DAGGER_ENGINE_NUM_CPU"); v != "" {
    if n, err := strconv.Atoi(v); err != nil || n <= 0 {
        return fmt.Errorf("invalid DAGGER_ENGINE_NUM_CPU %q", v)
    }
}

Try / catch

if _, err := dagger.Connect(ctx); err != nil && strings.Contains(err.Error(), "parse DAGGER_ENGINE_NUM_CPU") {
    os.Unsetenv("DAGGER_ENGINE_NUM_CPU")
    // retry connect
}

Prevention

When it happens

Trigger: Calling dagger.Connect() in a nested session where DAGGER_ENGINE_NUM_CPU is set to a non-integer string like "four", "4.0", or " 4".

Common situations: Users setting CPU limits as floats or with units ("4cpus"); Kubernetes-style resource strings pasted into the env; quoting artifacts from shell profiles.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


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